Pallial transition state cells

Extract apical progenitors

We perform Kmeans clustering on the 4 cell state scores :

  • Sub-pallial neurons SP
  • Pallial neurons Pal
  • Sub-pallial BP SP.BP
  • Pallial BP Pal.BP

We then extract the Pallial cells branche. We also excludes CR cells cluster form the trajectory inference.

#Remove the sub-pallial cells branche
MeanKclust.SPscore <- aggregate(SP_signature1 ~ kmeanClust, Allcells.data@meta.data, mean)
SPclust <- MeanKclust.SPscore %>% filter(SP_signature1 == max(SP_signature1)) %>% pull(kmeanClust)

SP.cells <- Allcells.data@meta.data %>% filter(kmeanClust == SPclust) %>% pull(Barcodes)

# Remove cells not use for trajectory inference (Subpallial cells defined by kmeans, Late GABA neurons and CR cells)
Excluded.clusters <- Allcells.data@meta.data %>%
                  filter(Cluster.ident %in% grep("*Sub|GABA|LN.Glut.13|LN.Glut.14|LN.Glut.1$", unique(as.character(Allcells.data@ident)), value = T)) %>%
                  pull(Barcodes) 

# We further keep only pallial apical progenitor cluster among other AP clusters
MeanKclust.APscore <- aggregate(AP_signature1 ~ kmeanClust, Allcells.data@meta.data, mean)
APclust <- MeanKclust.APscore %>% filter(AP_signature1 == max(AP_signature1)) %>% pull(kmeanClust)

All.AP <- Allcells.data@meta.data %>% filter(kmeanClust == APclust) %>% pull(Barcodes)
Valide.AP <- Allcells.data@meta.data %>% filter(Cluster.ident %in% grep("Dorsal.Pallium|lateral.Pallium.1|lateral.Pallium.2|Ventral.Pallium",
                                                unique(as.character(Allcells.data@ident)), value = T)) %>% pull(Barcodes)

filtered.AP <- All.AP[!All.AP %in% Valide.AP]

#Remove all invalide cells + 3 pallial outlier cells
Cells.to.use <- rownames(Allcells.data@meta.data)[!rownames(Allcells.data@meta.data) %in% unique(c(SP.cells, Excluded.clusters, filtered.AP, c("ATTTCTGCACGGCCAT" , "CAAGTTGCAAGCCTAT", "CTACATTGTAGCTGCC")))]
Allcells.data <- SubsetData(Allcells.data, cells.use = Cells.to.use, subset.raw = T,  do.clean = F)

Velocity estimation

Velocity estimation and visualisation

## calculating cell knn ... done
## calculating convolved matrices ... done
## gene kNN ... scaling gene weights ... convolving matrices ... done
## fitting gamma coefficients ... done. succesfful fit for 2423 genes
## filtered out 3 out of 2423 genes due to low nmat-emat correlation
## filtered out 10 out of 2420 genes due to low nmat-emat slope
## calculating RNA velocity shift ... re-estimating gamma of individual genes ... done
## calculating RNA velocity shift ... done
## calculating extrapolated cell state ... done
## delta projections ... sqrt knn ... transition probs ... done
## calculating arrows ... done
## grid estimates ... grid.sd= 0.288576  min.arrow.size= 0.005771519  max.grid.arrow.length= 0.04106169  done
## expression shifts .... done

Compute cells’ fate bias along tpward each mature neuronal types

Prepare FateID input data

We restricted the analysis to the most variable genes as dertermined by the Seurat function “FindVariableGenes” excluding cell cylce phase genes

Compte the cells’ fate bias

## minnr: 10 
## minnrh: 30 
## test set size iteration 1 : 10 10 10 10 10 10 10 
## randomforest iteration 1 of 50 cells
## test set size iteration 2 : 10 10 10 10 10 10 10 
## randomforest iteration 2 of 62 cells
## test set size iteration 3 : 10 10 10 10 10 10 10 
## randomforest iteration 3 of 53 cells
## test set size iteration 4 : 10 10 10 10 10 10 10 
## randomforest iteration 4 of 55 cells
## test set size iteration 5 : 10 10 10 10 10 10 10 
## randomforest iteration 5 of 49 cells
## test set size iteration 6 : 10 10 10 10 10 10 10 
## randomforest iteration 6 of 48 cells
## test set size iteration 7 : 10 10 10 10 10 10 10 
## randomforest iteration 7 of 54 cells
## test set size iteration 8 : 10 10 10 10 10 10 10 
## randomforest iteration 8 of 49 cells
## test set size iteration 9 : 10 10 10 10 10 10 10 
## randomforest iteration 9 of 50 cells
## test set size iteration 10 : 10 10 10 10 10 10 10 
## randomforest iteration 10 of 51 cells
## test set size iteration 11 : 10 10 10 10 10 10 10 
## randomforest iteration 11 of 52 cells
## test set size iteration 12 : 10 10 10 10 10 10 10 
## randomforest iteration 12 of 44 cells
## test set size iteration 13 : 10 10 10 10 10 10 10 
## randomforest iteration 13 of 45 cells
## test set size iteration 14 : 10 10 10 10 10 10 10 
## randomforest iteration 14 of 42 cells
## test set size iteration 15 : 10 10 10 10 10 10 10 
## randomforest iteration 15 of 43 cells
## test set size iteration 16 : 10 10 10 10 10 10 10 
## randomforest iteration 16 of 40 cells
## test set size iteration 17 : 10 10 10 10 10 10 10 
## randomforest iteration 17 of 40 cells
## test set size iteration 18 : 10 10 10 10 10 10 10 
## randomforest iteration 18 of 37 cells
## test set size iteration 19 : 10 10 10 10 10 10 10 
## randomforest iteration 19 of 42 cells
## test set size iteration 20 : 10 10 10 10 10 10 10 
## randomforest iteration 20 of 43 cells
## test set size iteration 21 : 10 10 10 10 10 10 10 
## randomforest iteration 21 of 48 cells
## test set size iteration 22 : 10 10 10 10 10 10 10 
## randomforest iteration 22 of 47 cells
## test set size iteration 23 : 10 10 10 10 10 10 10 
## randomforest iteration 23 of 50 cells
## test set size iteration 24 : 10 10 10 10 10 10 10 
## randomforest iteration 24 of 52 cells
## test set size iteration 25 : 10 10 10 10 10 10 10 
## randomforest iteration 25 of 53 cells
## test set size iteration 26 : 10 10 10 10 10 10 10 
## randomforest iteration 26 of 57 cells
## test set size iteration 27 : 10 10 10 10 10 10 10 
## randomforest iteration 27 of 54 cells
## test set size iteration 28 : 10 10 10 10 10 10 10 
## randomforest iteration 28 of 49 cells
## test set size iteration 29 : 10 10 10 10 10 10 10 
## randomforest iteration 29 of 54 cells
## test set size iteration 30 : 10 10 10 10 10 10 10 
## randomforest iteration 30 of 51 cells
## test set size iteration 31 : 10 10 10 10 10 10 10 
## randomforest iteration 31 of 50 cells
## test set size iteration 32 : 10 10 10 10 10 10 10 
## randomforest iteration 32 of 55 cells
## test set size iteration 33 : 5 5 5 5 5 5 10 
## randomforest iteration 33 of 36 cells
## test set size iteration 34 : 10 10 10 10 10 10 10 
## randomforest iteration 34 of 56 cells
## test set size iteration 35 : 10 10 10 10 10 10 10 
## randomforest iteration 35 of 55 cells
## test set size iteration 36 : 10 10 10 10 10 10 10 
## randomforest iteration 36 of 55 cells
## test set size iteration 37 : 10 10 10 10 10 10 10 
## randomforest iteration 37 of 54 cells
## test set size iteration 38 : 10 10 10 10 10 10 10 
## randomforest iteration 38 of 56 cells
## test set size iteration 39 : 10 10 10 10 10 10 10 
## randomforest iteration 39 of 58 cells
## test set size iteration 40 : 10 10 10 10 10 10 10 
## randomforest iteration 40 of 47 cells
## test set size iteration 41 : 10 10 10 10 10 10 10 
## randomforest iteration 41 of 44 cells
## test set size iteration 42 : 10 10 10 10 10 10 10 
## randomforest iteration 42 of 30 cells
## test set size iteration 43 : 10 10 10 10 10 10 10 
## randomforest iteration 43 of 18 cells
## test set size iteration 44 : 10 10 10 10 10 10 10 
## randomforest iteration 44 of 2 cells

Import lineage bias into Seurat meta.data

Manuscript Fig. 7A and S7A

Manuscript Fig. 7A and S7A

Spring projection where cells are grouped according to the lineage for which they received the maximum nb of vote

Spring projection where cells are grouped according to the lineage for which they received the maximum nb of vote

Extract the Nr4a2 and Nfix “lineage” cells

Aligne cells along Pseudotime

We decided to use spring space dimensionality reduction to fit the principale curve because it has been calculated on all cells together. Thus reflecting pan neuronal differentiation axis of varation.

Find DEG between the two trajectories and along the pseudotime

Find direction of the DEG

We find direction of the DEG by calculating the area between curves (ABC) for branch-dependent genes by adapting the monocle package function calABCs. Genes specific ABC is computed on smoothed expression value over 100 points along the pseudotime

Cluster genes by expression profiles along the two trajectories

Nr4a2 neurons specific transcriptional trajectories

Manuscript Fig. 7D

Manuscript Fig. 7D

Nfix neurons specific transcriptional trajectories

Manuscript Fig. 7C

Manuscript Fig. 7C

Inspect genes which best predict early fate bias within BPs

Extract cells in BP state

Find genes which best classify BP between the 2 trajectories

Session Info

## [1] "25 novembre, 2020, 10,45"
## R version 3.6.3 (2020-02-29)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 18.04.5 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/atlas/libblas.so.3.10.3
## LAPACK: /usr/lib/x86_64-linux-gnu/atlas/liblapack.so.3.10.3
## 
## locale:
##  [1] LC_CTYPE=fr_FR.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=fr_FR.UTF-8        LC_COLLATE=fr_FR.UTF-8    
##  [5] LC_MONETARY=fr_FR.UTF-8    LC_MESSAGES=fr_FR.UTF-8   
##  [7] LC_PAPER=fr_FR.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
##  [1] splines   stats4    parallel  stats     graphics  grDevices utils    
##  [8] datasets  methods   base     
## 
## other attached packages:
##  [1] wesanderson_0.3.6   RColorBrewer_1.1-2  patchwork_0.0.1    
##  [4] ggExtra_0.9         reshape2_1.4.3      dplyr_0.8.3        
##  [7] seriation_1.2-9     velocyto.R_0.6      FateID_0.1.9       
## [10] monocle_2.14.0      DDRTree_0.1.5       irlba_2.3.3        
## [13] VGAM_1.1-2          Biobase_2.46.0      BiocGenerics_0.32.0
## [16] princurve_2.1.4     Seurat_2.3.4        Matrix_1.2-17      
## [19] cowplot_1.0.0       ggplot2_3.2.1      
## 
## loaded via a namespace (and not attached):
##   [1] snow_0.4-3           backports_1.1.5      Hmisc_4.3-0         
##   [4] plyr_1.8.4           igraph_1.2.5         lazyeval_0.2.2      
##   [7] densityClust_0.3     lle_1.1              fastICA_1.2-2       
##  [10] digest_0.6.25        foreach_1.4.7        htmltools_0.5.0     
##  [13] viridis_0.5.1        lars_1.2             gdata_2.18.0        
##  [16] magrittr_1.5         checkmate_1.9.4      cluster_2.1.0       
##  [19] mixtools_1.1.0       ROCR_1.0-7           limma_3.42.0        
##  [22] matrixStats_0.55.0   R.utils_2.9.0        docopt_0.6.1        
##  [25] askpass_1.1          colorspace_1.4-1     ggrepel_0.8.1       
##  [28] xfun_0.18            sparsesvd_0.2        crayon_1.3.4        
##  [31] jsonlite_1.7.0       zeallot_0.1.0        survival_2.44-1.1   
##  [34] zoo_1.8-6            iterators_1.0.12     ape_5.3             
##  [37] glue_1.4.1           registry_0.5-1       gtable_0.3.0        
##  [40] kernlab_0.9-29       prabclus_2.3-1       DEoptimR_1.0-8      
##  [43] scales_1.1.0         pheatmap_1.0.12      som_0.3-5.1         
##  [46] bibtex_0.4.2         miniUI_0.1.1.1       Rcpp_1.0.5          
##  [49] metap_1.1            dtw_1.21-3           xtable_1.8-4        
##  [52] viridisLite_0.3.0    htmlTable_1.13.2     reticulate_1.13     
##  [55] foreign_0.8-72       bit_4.0.4            proxy_0.4-23        
##  [58] mclust_5.4.5         SDMTools_1.1-221.1   Formula_1.2-3       
##  [61] tsne_0.1-3           umap_0.2.3.1         htmlwidgets_1.5.1   
##  [64] httr_1.4.1           FNN_1.1.3            gplots_3.0.1.1      
##  [67] fpc_2.2-3            acepack_1.4.1        modeltools_0.2-22   
##  [70] ica_1.0-2            farver_2.0.1         pkgconfig_2.0.3     
##  [73] R.methodsS3_1.7.1    flexmix_2.3-15       nnet_7.3-14         
##  [76] locfit_1.5-9.1       labeling_0.3         later_1.0.0         
##  [79] tidyselect_0.2.5     rlang_0.4.7          munsell_0.5.0       
##  [82] tools_3.6.3          ggridges_0.5.1       fastmap_1.0.1       
##  [85] evaluate_0.14        stringr_1.4.0        yaml_2.2.1          
##  [88] npsurv_0.4-0         knitr_1.26           bit64_4.0.2         
##  [91] fitdistrplus_1.0-14  robustbase_0.93-5    caTools_1.17.1.2    
##  [94] randomForest_4.6-14  purrr_0.3.3          RANN_2.6.1          
##  [97] pbapply_1.4-2        nlme_3.1-141         mime_0.7            
## [100] slam_0.1-46          R.oo_1.23.0          hdf5r_1.3.2.9000    
## [103] compiler_3.6.3       rstudioapi_0.11      png_0.1-7           
## [106] lsei_1.2-0           tibble_2.1.3         stringi_1.4.6       
## [109] highr_0.8            lattice_0.20-41      HSMMSingleCell_1.6.0
## [112] vctrs_0.2.0          pillar_1.4.2         lifecycle_0.1.0     
## [115] combinat_0.0-8       Rdpack_0.11-0        lmtest_0.9-37       
## [118] data.table_1.12.6    bitops_1.0-6         gbRd_0.4-11         
## [121] httpuv_1.5.2         pcaMethods_1.78.0    R6_2.4.1            
## [124] latticeExtra_0.6-28  promises_1.1.0       TSP_1.1-10          
## [127] KernSmooth_2.23-15   gridExtra_2.3        codetools_0.2-16    
## [130] MASS_7.3-53          gtools_3.8.1         assertthat_0.2.1    
## [133] openssl_1.4.1        withr_2.1.2          qlcMatrix_0.9.7     
## [136] mgcv_1.8-33          diptest_0.75-7       doSNOW_1.0.18       
## [139] grid_3.6.3           rpart_4.1-15         tidyr_1.0.0         
## [142] class_7.3-17         rmarkdown_2.5        segmented_1.0-0     
## [145] Rtsne_0.15           shiny_1.4.0          snowfall_1.84-6.1   
## [148] scatterplot3d_0.3-41 base64enc_0.1-3

  1. Institute of Psychiatry and Neuroscience of Paris, INSERM U1266, 75014, Paris, France

LS0tCnRpdGxlOiAiQ29tcGFyYWlzb24gb2YgVlAgYW5kIERQIGRlcml2ZWQgbmV1cm9ucyBkaWZmZXJlbnRpYXRpb24gdHJhamVjdG9yaWVzIgphdXRob3I6CiAgLSBNYXR0aGlldSBNb3JlYXVeW0luc3RpdHV0ZSBvZiBQc3ljaGlhdHJ5IGFuZCBOZXVyb3NjaWVuY2Ugb2YgUGFyaXMsIElOU0VSTSBVMTI2NiwgNzUwMTQsIFBhcmlzLCBGcmFuY2VdLCBtYXR0aGlldS5tb3JlYXVAaW5zZXJtLmZyCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OiAKICAgIGNvZGVfZG93bmxvYWQ6IHllcwogICAgZGZfcHJpbnQ6IHRpYmJsZQogICAgaGlnaGxpZ2h0OiBoYWRkb2NrCiAgICBpbmNsdWRlczoKICAgICAgaW5faGVhZGVyOiBoZWFkZXIuaHRtbAogICAgdGhlbWU6IGNvc21vCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA1CiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogeWVzCi0tLQoKYGBge2NzcywgZWNobz1GQUxTRX0KaDEgewogIGZvbnQtc2l6ZTogMzRweDsKICBtYXJnaW4tdG9wOiAycmVtOwogIG1hcmdpbi1ib3R0b206IDFyZW07CiAgY29sb3I6ICNlNjRkMDA7CiAgdGV4dC1kZWNvcmF0aW9uOiBub25lOwp9CmgxLnRpdGxlIHsKICBmb250LXNpemU6IDQwcHg7CiAgbWFyZ2luLXRvcDogMnJlbTsKICBtYXJnaW4tYm90dG9tOiAxcmVtOwogIHRleHQtYWxpZ246IGNlbnRlcjsKICB0ZXh0LWRlY29yYXRpb246IG5vbmU7CiAgY29sb3I6ICMwMDAwMDA7Cn0KaDIgewogIGZvbnQtc2l6ZTogMzBweDsKICBtYXJnaW4tdG9wOiAycmVtOwogIG1hcmdpbi1ib3R0b206IDFyZW07CiAgY29sb3I6ICMwMDAwMDA7Cn0KaDMgewogIGZvbnQtc2l6ZTogMjRweDsKICBtYXJnaW4tdG9wOiAycmVtOwogIG1hcmdpbi1ib3R0b206IDFyZW07CiAgY29sb3I6ICMwMDAwMDA7Cn0KaDQgewogIGZvbnQtc2l6ZTogMjBweDsKICBtYXJnaW4tdG9wOiAycmVtOwogIG1hcmdpbi1ib3R0b206IDFyZW07CiAgY29sb3I6ICMwMDAwMDA7Cn0KaDUgewogIGZvbnQtc2l6ZTogMThweDsKICBtYXJnaW4tdG9wOiAycmVtOwogIG1hcmdpbi1ib3R0b206IDFyZW07CiAgY29sb3I6ICMwMDAwMDA7Cn0KCi5zY3JvbGwtMTAwIHsKICBtYXgtaGVpZ2h0OiAyMDBweDsKICBvdmVyZmxvdy15OiBhdXRvOwogIGJhY2tncm91bmQtY29sb3I6IGluaGVyaXQ7Cn0KCnAgewogIGZvbnQtc2l6ZTogMTZweDsKfQpgYGAKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGZpZy5hbGlnbiA9ICdjZW50ZXInLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFKQpgYGAKCiMgTG9hZCBsaWJyYXJpZXMgYW5kIFFDRmlsdGVyZWQgZGF0YXNldAoKYGBge3IgfQojIExvYWQgbGlicmFyeQpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShwcmluY3VydmUpCmxpYnJhcnkobW9ub2NsZSkKbGlicmFyeShGYXRlSUQpCmxpYnJhcnkodmVsb2N5dG8uUikKbGlicmFyeShwYXJhbGxlbCkKbGlicmFyeShzZXJpYXRpb24pCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocmVzaGFwZTIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShjb3dwbG90KQpsaWJyYXJ5KGdnRXh0cmEpCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKbGlicmFyeSh3ZXNhbmRlcnNvbikKCiNTZXQgZ2dwbG90IHRoZW1lIGFzIGNsYXNzaWMKdGhlbWVfc2V0KHRoZW1lX2NsYXNzaWMoKSkKYGBgCgpgYGB7cn0KIyBMb2FkIHRoZSBmdWxsIGFubm90YXRlZCBkYXRhc2V0CkFsbGNlbGxzLmRhdGEgPC0gcmVhZFJEUygiLi9DbHVzdGVyZWQuY2VsbHMuUkRTIikKYGBgCgpgYGB7ciBmaWcuZGltPWMoOCwgNil9CmNvbG9ycyA8LSAgYygiIzk2OTY5NiIsCiAgICAgICAgICAgICAgdG9sb3dlcihjKCIjNjhCMDQxIiwgIiNFM0MxNDgiLCAiI0I3RDE3NCIsICIjODNDM0I4IiwgIiMwMDlGREEiLCAiIzNFNjlBQyIsICIjRTQ2QjZCIikpLAogICAgICAgICAgICAgICIjZWM3NTZkIiwgIiNjNzczYTciLCAiIzcyOTNjOCIsICIjYjc5ZjBiIiwgIiMzY2E3M2YiLCIjMzFiNmJkIiwKICAgICAgICAgICAgICAiI2ViY2IyZSIsICIjOWVjMjJmIiwgIiNhOTk2MWIiLCAiI2NjM2ExYiIsICIjY2M4Nzc4IiAsICIjZDE0YzhkIiwgIiM0Y2FiZGMiLCAiIzVhYjc5MyIsICIjZTc4MjNhIiwiI2U2YmI5YiIsICIjMDQ2YzlhIiwgIiM0Nzg0YTIiICwgIiM0OTkwYzkiKQoKRGltUGxvdChBbGxjZWxscy5kYXRhLAogICAgICAgIHJlZHVjdGlvbi51c2UgPSAic3ByaW5nIiwgCiAgICAgICAgZGltLjEgPSAxLAogICAgICAgIGRpbS4yID0gMiwKICAgICAgICBkby5sYWJlbD1ULAogICAgICAgIGxhYmVsLnNpemUgPSAyLAogICAgICAgIG5vLmxlZ2VuZCA9IEYsCiAgICAgICAgY29scy51c2UgPSBjb2xvcnMpCmBgYAoKIyBQYWxsaWFsIHRyYW5zaXRpb24gc3RhdGUgY2VsbHMKCiMjIEV4dHJhY3QgYXBpY2FsIHByb2dlbml0b3JzCgpXZSBwZXJmb3JtIEttZWFucyBjbHVzdGVyaW5nIG9uIHRoZSA0IGNlbGwgc3RhdGUgc2NvcmVzIDoKCi0gU3ViLXBhbGxpYWwgbmV1cm9ucyBgU1BgCi0gUGFsbGlhbCBuZXVyb25zIGBQYWxgCi0gU3ViLXBhbGxpYWwgQlAgYFNQLkJQYAotIFBhbGxpYWwgQlAgYFBhbC5CUGAKCmBgYHtyfQojQ2FsY3VsYXRlIFBhbGxpYWwgYW5kIFN1Yi1wYWxsaWFsIEJQIHNjb3JlcwpQYWwuQlAuZ2VuZXMgPC0gYygiRW9tZXMiLCAiTmV1cm9nMiIsICJOZXVyb2cxIiwgIlBybXQ4IiwgIk5ycDEiKQpnZW5lcy5saXN0IDwtIGxpc3QoUGFsLkJQLmdlbmVzKQplbnJpY2gubmFtZSA8LSAiUGFsLkJQX3NpZ25hdHVyZSIKQWxsY2VsbHMuZGF0YSA8LSBBZGRNb2R1bGVTY29yZShBbGxjZWxscy5kYXRhLCBnZW5lcy5saXN0ID0gZ2VuZXMubGlzdCwgZ2VuZXMucG9vbCA9IE5VTEwsIG4uYmluID0gNSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkLnVzZSA9IDEsIGN0cmwuc2l6ZSA9IGxlbmd0aChnZW5lcy5saXN0KSwgdXNlLmsgPSBGQUxTRSwgZW5yaWNoLm5hbWUgPSBlbnJpY2gubmFtZSAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tLnNlZWQgPSAxKQoKClNQLkJQLmdlbmVzIDwtIGMoIkRseDEiLCAiRGx4MiIsICJEbHg1IiwiQXNjbDEiLCAiR3N4MiIpCmdlbmVzLmxpc3QgPC0gbGlzdChTUC5CUC5nZW5lcykKZW5yaWNoLm5hbWUgPC0gIlNQLkJQX3NpZ25hdHVyZSIKQWxsY2VsbHMuZGF0YSA8LSBBZGRNb2R1bGVTY29yZShBbGxjZWxscy5kYXRhLCBnZW5lcy5saXN0ID0gZ2VuZXMubGlzdCwgZ2VuZXMucG9vbCA9IE5VTEwsIG4uYmluID0gNSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkLnVzZSA9IDEsIGN0cmwuc2l6ZSA9IGxlbmd0aChnZW5lcy5saXN0KSwgdXNlLmsgPSBGQUxTRSwgZW5yaWNoLm5hbWUgPSBlbnJpY2gubmFtZSAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tLnNlZWQgPSAxKQpgYGAKCmBgYHtyfQpzZXQuc2VlZCgxMDApCiMgUnVuIEttZWFucyBjbHVzdGVyaW5nCmNsIDwtIGttZWFucyhjYmluZChBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRTUF9zaWduYXR1cmUxLAogICAgICAgICAgICAgICAgICAgQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkUGFsX3NpZ25hdHVyZTEsCiAgICAgICAgICAgICAgICAgICBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRTUC5CUF9zaWduYXR1cmUxLAogICAgICAgICAgICAgICAgICAgQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkUGFsLkJQX3NpZ25hdHVyZTEpLCA0KQoKQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEka21lYW5DbHVzdCA8LSBwYXN0ZTAoIkNsdXN0LiIsY2wkY2x1c3RlcikKYGBgCgpgYGB7ciBmaWcuZGltPWMoNS4zLCA0KX0KY29sLnBhbCA8LSB3ZXNfcGFsZXR0ZSgiR3JhbmRCdWRhcGVzdDEiLCA0LCB0eXBlID0gImRpc2NyZXRlIikKCnAxIDwtIGdncGxvdChBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSwgYWVzKHg9U1Bfc2lnbmF0dXJlMSwgeT1QYWxfc2lnbmF0dXJlMSwgY29sb3VyID0ga21lYW5DbHVzdCkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWNvbC5wYWwpICsKICBnZW9tX3BvaW50KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQpnZ01hcmdpbmFsKHAxLCB0eXBlID0gImhpc3RvZ3JhbSIsIGZpbGw9ImxpZ2h0Z3JleSIpCgpEaW1QbG90KEFsbGNlbGxzLmRhdGEsCiAgICAgICAgZ3JvdXAuYnkgPSAia21lYW5DbHVzdCIsCiAgICAgICAgcmVkdWN0aW9uLnVzZSA9ICJzcHJpbmciLAogICAgICAgIGNvbHMudXNlID0gY29sLnBhbCwKICAgICAgICBkaW0uMSA9IDEsCiAgICAgICAgZGltLjIgPSAyLAogICAgICAgIGRvLmxhYmVsPVQsCiAgICAgICAgbGFiZWwuc2l6ZSA9IDQsCiAgICAgICAgbm8ubGVnZW5kID0gRikKYGBgCgpXZSB0aGVuIGV4dHJhY3QgdGhlIFBhbGxpYWwgY2VsbHMgYnJhbmNoZS4gV2UgYWxzbyBleGNsdWRlcyBDUiBjZWxscyBjbHVzdGVyIGZvcm0gdGhlIHRyYWplY3RvcnkgaW5mZXJlbmNlLgoKYGBge3J9CiNSZW1vdmUgdGhlIHN1Yi1wYWxsaWFsIGNlbGxzIGJyYW5jaGUKTWVhbktjbHVzdC5TUHNjb3JlIDwtIGFnZ3JlZ2F0ZShTUF9zaWduYXR1cmUxIH4ga21lYW5DbHVzdCwgQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEsIG1lYW4pClNQY2x1c3QgPC0gTWVhbktjbHVzdC5TUHNjb3JlICU+JSBmaWx0ZXIoU1Bfc2lnbmF0dXJlMSA9PSBtYXgoU1Bfc2lnbmF0dXJlMSkpICU+JSBwdWxsKGttZWFuQ2x1c3QpCgpTUC5jZWxscyA8LSBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSAlPiUgZmlsdGVyKGttZWFuQ2x1c3QgPT0gU1BjbHVzdCkgJT4lIHB1bGwoQmFyY29kZXMpCgojIFJlbW92ZSBjZWxscyBub3QgdXNlIGZvciB0cmFqZWN0b3J5IGluZmVyZW5jZSAoU3VicGFsbGlhbCBjZWxscyBkZWZpbmVkIGJ5IGttZWFucywgTGF0ZSBHQUJBIG5ldXJvbnMgYW5kIENSIGNlbGxzKQpFeGNsdWRlZC5jbHVzdGVycyA8LSBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSAlPiUKICAgICAgICAgICAgICAgICAgZmlsdGVyKENsdXN0ZXIuaWRlbnQgJWluJSBncmVwKCIqU3VifEdBQkF8TE4uR2x1dC4xM3xMTi5HbHV0LjE0fExOLkdsdXQuMSQiLCB1bmlxdWUoYXMuY2hhcmFjdGVyKEFsbGNlbGxzLmRhdGFAaWRlbnQpKSwgdmFsdWUgPSBUKSkgJT4lCiAgICAgICAgICAgICAgICAgIHB1bGwoQmFyY29kZXMpIAoKIyBXZSBmdXJ0aGVyIGtlZXAgb25seSBwYWxsaWFsIGFwaWNhbCBwcm9nZW5pdG9yIGNsdXN0ZXIgYW1vbmcgb3RoZXIgQVAgY2x1c3RlcnMKTWVhbktjbHVzdC5BUHNjb3JlIDwtIGFnZ3JlZ2F0ZShBUF9zaWduYXR1cmUxIH4ga21lYW5DbHVzdCwgQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEsIG1lYW4pCkFQY2x1c3QgPC0gTWVhbktjbHVzdC5BUHNjb3JlICU+JSBmaWx0ZXIoQVBfc2lnbmF0dXJlMSA9PSBtYXgoQVBfc2lnbmF0dXJlMSkpICU+JSBwdWxsKGttZWFuQ2x1c3QpCgpBbGwuQVAgPC0gQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEgJT4lIGZpbHRlcihrbWVhbkNsdXN0ID09IEFQY2x1c3QpICU+JSBwdWxsKEJhcmNvZGVzKQpWYWxpZGUuQVAgPC0gQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEgJT4lIGZpbHRlcihDbHVzdGVyLmlkZW50ICVpbiUgZ3JlcCgiRG9yc2FsLlBhbGxpdW18bGF0ZXJhbC5QYWxsaXVtLjF8bGF0ZXJhbC5QYWxsaXVtLjJ8VmVudHJhbC5QYWxsaXVtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pcXVlKGFzLmNoYXJhY3RlcihBbGxjZWxscy5kYXRhQGlkZW50KSksIHZhbHVlID0gVCkpICU+JSBwdWxsKEJhcmNvZGVzKQoKZmlsdGVyZWQuQVAgPC0gQWxsLkFQWyFBbGwuQVAgJWluJSBWYWxpZGUuQVBdCgojUmVtb3ZlIGFsbCBpbnZhbGlkZSBjZWxscyArIDMgcGFsbGlhbCBvdXRsaWVyIGNlbGxzCkNlbGxzLnRvLnVzZSA8LSByb3duYW1lcyhBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSlbIXJvd25hbWVzKEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhKSAlaW4lIHVuaXF1ZShjKFNQLmNlbGxzLCBFeGNsdWRlZC5jbHVzdGVycywgZmlsdGVyZWQuQVAsIGMoIkFUVFRDVEdDQUNHR0NDQVQiICwgIkNBQUdUVEdDQUFHQ0NUQVQiLCAiQ1RBQ0FUVEdUQUdDVEdDQyIpKSldCkFsbGNlbGxzLmRhdGEgPC0gU3Vic2V0RGF0YShBbGxjZWxscy5kYXRhLCBjZWxscy51c2UgPSBDZWxscy50by51c2UsIHN1YnNldC5yYXcgPSBULCAgZG8uY2xlYW4gPSBGKQpgYGAKCmBgYHtyIGZpZy5kaW09Yyg4LCA2KX0KY29sb3JzIDwtICBjKCIjOTY5Njk2IiwKICAgICAgICAgICAgICB0b2xvd2VyKGMoIiM2OEIwNDEiLCAiI0UzQzE0OCIsICIjQjdEMTc0IiwgIiNFNDZCNkIiKSksCiAgICAgICAgICAgICAgIiNjYzNhMWIiLCAiI2NjODc3OCIgLCAiI2QxNGM4ZCIsICIjNGNhYmRjIiwgIiM1YWI3OTMiLCAiI2U3ODIzYSIsIiNlNmJiOWIiLCAiIzA0NmM5YSIsICIjNDc4NGEyIiAsICIjNDk5MGM5IikKCkRpbVBsb3QoQWxsY2VsbHMuZGF0YSwKICAgICAgICByZWR1Y3Rpb24udXNlID0gInNwcmluZyIsIAogICAgICAgIGRpbS4xID0gMSwKICAgICAgICBkaW0uMiA9IDIsCiAgICAgICAgZG8ubGFiZWw9VCwKICAgICAgICBsYWJlbC5zaXplID0gMiwKICAgICAgICBuby5sZWdlbmQgPSBULAogICAgICAgIGNvbHMudXNlID0gY29sb3JzKQpgYGAKCiMjIEZpbHRlciB0aGUgZ2VuZSBjb3VudHMgbWF0cml4CgpgYGB7cn0KIyBGaWx0ZXIgZ2VuZXMKbnVtLmNlbGxzIDwtIE1hdHJpeDo6cm93U3VtcyhBbGxjZWxscy5kYXRhQHJhdy5kYXRhID4gMCkKZ2VuZXMudXNlIDwtIG5hbWVzKHggPSBudW0uY2VsbHNbd2hpY2goeCA9IG51bS5jZWxscyA+PSAyMCldKQpBbGxjZWxscy5kYXRhQHJhdy5kYXRhIDwtIEFsbGNlbGxzLmRhdGFAcmF3LmRhdGFbZ2VuZXMudXNlLCBdCgojIE5vcm1hbGl6YXRpb24gYW5kIHZhcmlhYmxlIGdlbmUgc2VsZWN0aW9uCkFsbGNlbGxzLmRhdGEgPC0gTm9ybWFsaXplRGF0YShvYmplY3QgPSBBbGxjZWxscy5kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiTG9nTm9ybWFsaXplIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZS5mYWN0b3IgPSByb3VuZChtZWRpYW4oQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkblVNSSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheS5wcm9ncmVzcyA9IEYpCgpBbGxjZWxscy5kYXRhIDwtIEZpbmRWYXJpYWJsZUdlbmVzKG9iamVjdCA9IEFsbGNlbGxzLmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVhbi5mdW5jdGlvbiA9IEV4cE1lYW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGVyc2lvbi5mdW5jdGlvbiA9IExvZ1ZNUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4Lmxvdy5jdXRvZmYgPSAwLjAzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHguaGlnaC5jdXRvZmYgPSA0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkuY3V0b2ZmID0gMiwgZG8ucGxvdCA9IEYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheS5wcm9ncmVzcyA9IEYpCmBgYAoKIyBWZWxvY2l0eSBlc3RpbWF0aW9uCgojIyBTZXQgQ2x1c3RlciBJZCBhbmQgY29sb3IgcGFsZXR0ZSBmb3IgdmVsb2NpdHkgaW50ZXJuYWwgcGxvdHRpbmcgZnVuY3Rpb25zCmBgYHtyfQojIFRha2UgdGhlIGNsdXN0ZXIgaWQgZnJvbSBTZXVyYXQgYW5hbHlzaXMKY2x1c3Rlci5sYWJlbCA8LSBBbGxjZWxscy5kYXRhQGlkZW50CkNsdXN0ZXIuaWRlbnQgPC0gYXMuY2hhcmFjdGVyKEFsbGNlbGxzLmRhdGFAaWRlbnQpCgojU2V0IGNvbG9yIFBhbGV0dGUgZm9yIGxheW91dApwYWxldHRlIDwtIGMoc2NhbGVzOjpodWVfcGFsKCkobGVuZ3RoKHVuaXF1ZShDbHVzdGVyLmlkZW50KSkpKQpjb2xvcnNpZGVudCA8LSBjYmluZChpZGVudCA9IHNvcnQodW5pcXVlKENsdXN0ZXIuaWRlbnQpKSwKICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gYygiIzk2OTY5NiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9sb3dlcihjKCIjNjhCMDQxIiwgIiNFM0MxNDgiLCAiI0I3RDE3NCIsICIjRTQ2QjZCIikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIjY2MzYTFiIiwgIiNjYzg3NzgiICwgIiNkMTRjOGQiLCAiIzRjYWJkYyIsICIjNWFiNzkzIiwgIiNlNzgyM2EiLCIjZTZiYjliIiwgIiMwNDZjOWEiLCAiIzQ3ODRhMiIgLCAiIzQ5OTBjOSIpICkKCiNDcmVhdGUgYW5ub3RhdGlvbiBkYXRhLmZyYW1lCkNlbGxzLkNvbG9yLmRmIDwtIGRhdGEuZnJhbWUoc2FtcGxlX25hbWUgPSByb3cubmFtZXMoQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW1hcnlfdHlwZV9sYWJlbCA9IGFzLmNoYXJhY3RlcihDbHVzdGVyLmlkZW50KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmltYXJ5X3R5cGVfY29sb3IgPSBhcy5jaGFyYWN0ZXIoY29sb3JzaWRlbnRbbWF0Y2goQ2x1c3Rlci5pZGVudCwgY29sb3JzaWRlbnRbLDFdKSwyXSkpCgoKY2VsbC5jb2xvcnMgPC0gQ2VsbHMuQ29sb3IuZGYkcHJpbWFyeV90eXBlX2NvbG9yCm5hbWVzKGNlbGwuY29sb3JzKSA8LSBDZWxscy5Db2xvci5kZiRzYW1wbGVfbmFtZQoKcm0oQ2VsbHMuQ29sb3IuZGYsY29sb3JzaWRlbnQscGFsZXR0ZSkKYGBgCgojIyBMb2FkIHZlbG9jaXRvIExvb20gZmlsZSBjb250YWluaW5nIHNwbGljZWQgLyB1bnNwbGljZWQgZ2VuZSBjb3VudCBtYXRyaXgKYGBge3J9CiNMb2FkIExvb20gZmlsZSBjb250YWluaW5nIFNwbGljZWQgVlMgVW5zcGxpY2VkIHRyYW5zY3JpcHRzIGNvdW50IG1hdHJpY2VzCkxvb21QYXRoIDwtICIuL3ZlbG9jeXRvL0UxMi1XVC5sb29tIiAKbGRhdCA8LSByZWFkLmxvb20ubWF0cmljZXMoTG9vbVBhdGgpCgpCYXJjb2Rlc1ZlbG9jaXR5IDwtIHN0cmluZ2k6OnN0cmlfc3ViKGxkYXQkc3BsaWNlZEBEaW1uYW1lc1tbMl1dLDQwLDU1KQoKbGRhdCRzcGxpY2VkQERpbW5hbWVzW1syXV0gPC0gQmFyY29kZXNWZWxvY2l0eQpsZGF0JHVuc3BsaWNlZEBEaW1uYW1lc1tbMl1dIDwtIEJhcmNvZGVzVmVsb2NpdHkKbGRhdCRhbWJpZ3VvdXNARGltbmFtZXNbWzJdXSA8LSBCYXJjb2Rlc1ZlbG9jaXR5CgojRmlsdGVyIG1hdHJpeCBieSBiYXJjb2RlcyBwcmVzZW50IGluIFNldXJhdCBvYmplY3QgKGNlbGwgdG8gcmV0YWluIGZvciB0aGUgYW5hbHlzaXMpCmxkYXQkc3BsaWNlZCA8LSBsZGF0JHNwbGljZWRbLHJvd25hbWVzKEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhKV0KbGRhdCR1bnNwbGljZWQgPC0gbGRhdCR1bnNwbGljZWRbLHJvd25hbWVzKEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhKV0KCiNSZW1vdmUgZ2VuZXMgd2l0aCBkdXBsaWNhdGVkIHJvd3MKbGRhdCRzcGxpY2VkIDwtIGxkYXQkc3BsaWNlZFshZHVwbGljYXRlZChsZGF0W1sidW5zcGxpY2VkIl1dQERpbW5hbWVzW1sxXV0pLF0KbGRhdCR1bnNwbGljZWQgPC0gbGRhdCR1bnNwbGljZWRbIWR1cGxpY2F0ZWQobGRhdFtbInVuc3BsaWNlZCJdXUBEaW1uYW1lc1tbMV1dKSxdCgojQ2xlYW4gd29ya3NwYWNlCnJtKGxpc3Q9bHMoKVshbHMoKSAlaW4lIGMoIkFsbGNlbGxzLmRhdGEiLCAibGRhdCIsICJjZWxsLmNvbG9ycyIsICJjbHVzdGVyLmxhYmVsIildKQpgYGAKCiMjIFNlbGVjdCBnZW5lcyB0byB1c2UgZm9yIHZlbG9jaXR5IGVzdGltYXRpb24gYW5kIHNldCBjZWxscycgYXNzb2NpYXRpb24gbWV0cmljCmBgYHtyfQpzcGxpY2VkIDwtIGxkYXQkc3BsaWNlZAp1bnNwbGljZWQgPC0gbGRhdCR1bnNwbGljZWQKCiNGaWx0ZXIgZ2VuZXMgYnkgY2x1c3RlciBleHByZXNzaW9uCkZpbHRlcmVkLnNwbGljZWQgPC0gZmlsdGVyLmdlbmVzLmJ5LmNsdXN0ZXIuZXhwcmVzc2lvbihzcGxpY2VkLGNsdXN0ZXIubGFiZWwsbWluLm1heC5jbHVzdGVyLmF2ZXJhZ2UgPSAwLjMpCkZpbHRlcmVkLnVuc3BsaWNlZCA8LSBmaWx0ZXIuZ2VuZXMuYnkuY2x1c3Rlci5leHByZXNzaW9uKHVuc3BsaWNlZCxjbHVzdGVyLmxhYmVsLG1pbi5tYXguY2x1c3Rlci5hdmVyYWdlID0gMC4zKQoKIyBGaWx0ZXIgQ2VsbCBjeWNsZSBhc3NvY2lhdGVkIGdlbmVzIHRvIHN0cmVzcyBvbmx5IHRoZSBuZXVyb2dlbmljIGNvbXBvc2FudGUKQ0NnZW5lcyA8LSBhcy5jaGFyYWN0ZXIocmVhZC50YWJsZSgiLi9Qcm9nZW5pdG9ycy9DZWxsQ3ljbGVHZW5lcy5jc3YiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSBGKVssMV0pCgpGaWx0ZXJlZC5zcGxpY2VkICA8LSBGaWx0ZXJlZC5zcGxpY2VkWyFyb3duYW1lcyhGaWx0ZXJlZC5zcGxpY2VkKSAlaW4lIENDZ2VuZXMsXQpGaWx0ZXJlZC51bnNwbGljZWQgPC0gRmlsdGVyZWQudW5zcGxpY2VkWyFyb3duYW1lcyhGaWx0ZXJlZC51bnNwbGljZWQpICVpbiUgQ0NnZW5lcyxdCmBgYAoKCmBgYHtyfQpBbGxjZWxscy5kYXRhIDwtIFJ1blBDQShvYmplY3QgPSBBbGxjZWxscy5kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBwY3MuY29tcHV0ZSA9IDIwLAogICAgICAgICAgICAgICAgICAgICAgICBkby5wcmludCA9IEYpCgojU2VsZWN0IGFzc29jaWF0aW9uIG1ldHJpYyB1c2UgZm9yIHZlbG9jaXR5IGVzdGltYXRpb24KY2VsbC5kaXN0IDwtIGFzLmRpc3QoMS1hcm1hQ29yKHQoQWxsY2VsbHMuZGF0YUBkciRwY2FAY2VsbC5lbWJlZGRpbmdzKSkpCmBgYAoKIyMgVmVsb2NpdHkgZXN0aW1hdGlvbiBhbmQgdmlzdWFsaXNhdGlvbgpgYGB7cn0KI1ZlbG9jaXR5IGVzdGltYXRpb24KZml0LnF1YW50aWxlIDwtIDAuMDQKcnZlbC5jZCA8LSBnZW5lLnJlbGF0aXZlLnZlbG9jaXR5LmVzdGltYXRlcyhGaWx0ZXJlZC5zcGxpY2VkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZpbHRlcmVkLnVuc3BsaWNlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWx0YVQ9MSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrQ2VsbHMgPSA4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtHZW5lcyA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuZGlzdD1jZWxsLmRpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZml0LnF1YW50aWxlPWZpdC5xdWFudGlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuLmNvcmVzID0gZGV0ZWN0Q29yZXMoKSAtMikKYGBgCgpgYGB7ciBmaWcuc2hvdz0naGlkZSd9CiNWZWxvY2l0eSBvbiBlbWJlZGRpbmcKZW1iIDwtIEFsbGNlbGxzLmRhdGFAZHIkc3ByaW5nQGNlbGwuZW1iZWRkaW5ncy81MAoKU3ByaW5nLnZlbG8gPC0gc2hvdy52ZWxvY2l0eS5vbi5lbWJlZGRpbmcuY29yKGVtYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ2ZWwuY2QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuPTUwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGU9J3NxcnQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2V4PTAuOCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFycm93LnNjYWxlPTAuNywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3cuZ3JpZC5mbG93PVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW4uZ3JpZC5jZWxsLm1hc3M9MC41LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JpZC5uPTQwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJyb3cubHdkPTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkby5wYXI9RiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuYm9yZGVyLmFscGhhID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNlbGwuY29sb3JzPWNlbGwuY29sb3JzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbi5zY2FsaW5nID0gVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybi5kZXRhaWxzPSBULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbi5jb3JlPSBkZXRlY3RDb3JlcygpIC0yKQoKYGBgCgpgYGB7ciBmaWcuZGltPWMoOSwgNil9ClNwcmluZy5wbG90IDwtIGFzLmRhdGEuZnJhbWUoQWxsY2VsbHMuZGF0YUBkciRzcHJpbmdAY2VsbC5lbWJlZGRpbmdzLzUwKSAlPiUKICAgICAgICAgICAgICAgbXV0YXRlKHgwID0gU3ByaW5nLnZlbG8kYXJyb3dzWywgIngwIl0sCiAgICAgICAgICAgICAgICAgICAgICB4MSA9IFNwcmluZy52ZWxvJGFycm93c1ssICJ4MSJdLAogICAgICAgICAgICAgICAgICAgICAgeTAgPSBTcHJpbmcudmVsbyRhcnJvd3NbLCAieTAiXSwKICAgICAgICAgICAgICAgICAgICAgIHkxID0gU3ByaW5nLnZlbG8kYXJyb3dzWywgInkxIl0pICU+JQogICAgICAgICAgICAgICBtdXRhdGUoeDIgPSB4MCArICh4MSAtIHgwKSwKICAgICAgICAgICAgICAgICAgICAgIHkyID0geTAgKyAoeTEgLSB5MCkpICU+JQogICAgICAgICAgICAgICBtdXRhdGUoQ2x1c3RlciA9IEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJENsdXN0ZXIuaWRlbnQpCgpjb2xvcnMgPC0gYygiIzk2OTY5NiIsCiAgICAgICAgICAgIHRvbG93ZXIoYygiIzY4QjA0MSIsICIjRTNDMTQ4IiwgIiNCN0QxNzQiLCAiI0U0NkI2QiIpKSwKICAgICAgICAgICAgIiNjYzNhMWIiLCAiI2NjODc3OCIgLCAiI2QxNGM4ZCIsICIjNGNhYmRjIiwgIiM1YWI3OTMiLCAiI2U3ODIzYSIsIiNlNmJiOWIiLCAiIzA0NmM5YSIsICIjNDc4NGEyIiAsICIjNDk5MGM5IikKCmdncGxvdChTcHJpbmcucGxvdCkgKwogICAgZ2VvbV9wb2ludChhZXMoeCA9IHNwcmluZzEsIHkgPSBzcHJpbmcyLCBjb2xvdXIgPSBDbHVzdGVyKSkgKwogICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9ycykgKwogICAgZ2VvbV9zZWdtZW50KGFlcyh4ID0geDAsIHhlbmQgPSB4MiwgeSA9IHkwLCB5ZW5kID0geTIpLAogICAgICAgICAgICAgICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgzLCAicG9pbnRzIiksIHR5cGUgPSAiY2xvc2VkIiksCiAgICAgICAgICAgICAgICAgY29sb3VyID0gImdyZXkyMCIsIGFscGhhID0gMC44KSArIAogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQpgYGAKCmBgYHtyIGZpZy5kaW09Yyg5LCA2KX0KZ2xvYmFsLnZlbC5hcnJvdyA8LSBTcHJpbmcudmVsbyRnYXJyb3dzICU+JQogICAgICAgICAgICAgICAgICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUKICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKHgyID0geDAgKyAoeDEgLSB4MCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB5MiA9IHkwICsgKHkxIC0geTApKQoKZ2dwbG90KFNwcmluZy5wbG90KSArCiAgICBnZW9tX3BvaW50KGFlcyh4ID0gc3ByaW5nMSwgeSA9IHNwcmluZzIsIGNvbG91ciA9IENsdXN0ZXIpKSArCiAgICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzKSArCiAgICBnZW9tX3NlZ21lbnQoZGF0YSA9IGdsb2JhbC52ZWwuYXJyb3csCiAgICAgICAgICAgICAgICAgYWVzKHggPSB4MCwgeGVuZCA9IHgyLCB5ID0geTAsIHllbmQgPSB5MiksCiAgICAgICAgICAgICAgICAgc2l6ZSA9IDEsCiAgICAgICAgICAgICAgICAgYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDMsICJwb2ludHMiKSwgdHlwZSA9ICJvcGVuIiksCiAgICAgICAgICAgICAgICAgY29sb3VyID0gImdyZXkyMCIsIGFscGhhID0gMC44KSArIAogICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQpgYGAKCmBgYHtyfQpybShsaXN0ID0gbHMoKVshbHMoKSAlaW4lICJBbGxjZWxscy5kYXRhIl0pCmBgYAoKIyBDb21wdXRlIGNlbGxzJyBmYXRlIGJpYXMgYWxvbmcgdHB3YXJkIGVhY2ggbWF0dXJlIG5ldXJvbmFsIHR5cGVzCgojIyBQcmVwYXJlIEZhdGVJRCBpbnB1dCBkYXRhCgpgYGB7cn0KIyBGYXRhSUQgcmVxdWllcmVzIHRoZSB0ZXJtaW5hbCBjbHVzdGVycyBJRCB0byBiZSBpbnRlZ2VycwpUZXJtaW5hbEZhdGVzIDwtIGdyZXAoIjE2fDI0fDIyfDE5fDI2fDIwfDIxIiwgdW5pcXVlKGFzLmNoYXJhY3RlcihBbGxjZWxscy5kYXRhQGlkZW50KSksIHZhbHVlID0gVCkKCkFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJE5ld0NsdXN0ZXJJRCA8LSBzYXBwbHkoYXMuY2hhcmFjdGVyKEFsbGNlbGxzLmRhdGFAaWRlbnQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIGlmKHggPT0gVGVybWluYWxGYXRlc1sxXSl7eD0xfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoeD09IFRlcm1pbmFsRmF0ZXNbMl0pe3g9Mn0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKHg9PSBUZXJtaW5hbEZhdGVzWzNdKXt4PTN9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih4PT0gVGVybWluYWxGYXRlc1s0XSl7eD00fQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoeD09IFRlcm1pbmFsRmF0ZXNbNV0pe3g9NX0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKHg9PSBUZXJtaW5hbEZhdGVzWzZdKXt4PTZ9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih4PT0gVGVybWluYWxGYXRlc1s3XSl7eD03fQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2V7eD14fSkKQWxsY2VsbHMuZGF0YSA8LSBTZXRBbGxJZGVudChBbGxjZWxscy5kYXRhLCBpZCA9ICJOZXdDbHVzdGVySUQiKQpgYGAKCmBgYHtyIGZpZy5kaW09Yyg4LCA2KX0KY29sb3JzIDwtICBjKCIjY2M4Nzc4IiAsICIjZDE0YzhkIiwgIiM0Y2FiZGMiLCAiIzVhYjc5MyIsICIjZTc4MjNhIiwiI2U2YmI5YiIsIiNjYzNhMWIiLAogICAgICAgICAgICAgIiM5Njk2OTYiLAogICAgICAgICAgICAgIHRvbG93ZXIoYygiIzY4QjA0MSIsICIjRTNDMTQ4IiwgIiNCN0QxNzQiLCAiI0U0NkI2QiIpKSwKICAgICAgICAgICAgICAiIzA0NmM5YSIsICIjNDc4NGEyIiAsICIjNDk5MGM5IikKCkRpbVBsb3QoQWxsY2VsbHMuZGF0YSwKICAgICAgICByZWR1Y3Rpb24udXNlID0gInNwcmluZyIsIAogICAgICAgIGRpbS4xID0gMSwKICAgICAgICBkaW0uMiA9IDIsCiAgICAgICAgZG8ubGFiZWw9VCwKICAgICAgICBsYWJlbC5zaXplID0gNCwKICAgICAgICBuby5sZWdlbmQgPSBGLAogICAgICAgIGNvbHMudXNlID0gY29sb3JzKQpgYGAKCldlIHJlc3RyaWN0ZWQgdGhlIGFuYWx5c2lzIHRvIHRoZSBtb3N0IHZhcmlhYmxlIGdlbmVzIGFzIGRlcnRlcm1pbmVkIGJ5IHRoZSBTZXVyYXQgZnVuY3Rpb24gIkZpbmRWYXJpYWJsZUdlbmVzIiBleGNsdWRpbmcgY2VsbCBjeWxjZSBwaGFzZSBnZW5lcwoKYGBge3J9CiMgRXhjbHVkZSBjZWxsIGN5Y2xlIGFzc29jaWF0ZWQgZ2VuZXMKQ0NnZW5lcyA8LSBhcy5jaGFyYWN0ZXIocmVhZC50YWJsZSgiLi9Qcm9nZW5pdG9ycy9DZWxsQ3ljbGVHZW5lcy5jc3YiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSBGKVssMV0pCklucHV0LmdlbmVzIDwtIEFsbGNlbGxzLmRhdGFAdmFyLmdlbmVzWyFBbGxjZWxscy5kYXRhQHZhci5nZW5lcyAlaW4lIENDZ2VuZXNdCgojIEZhdGVJRCByZXF1aWVyZXMgdGhlIGV4cHJlc3Npb24gbWF0cml4IHRvIGJlIGEgZGF0YWZyYW1lCk5vcm0uTWF0IDwtIGFzLmRhdGEuZnJhbWUoYXMubWF0cml4KEFsbGNlbGxzLmRhdGFAZGF0YVtJbnB1dC5nZW5lcyxdKSkKCiMgU2V0IGEgY2x1c3RlciBhc3NpZ25tZW50IGZhY3RvciBmb3IgZWFjaCBjZWxscwpDbHVzdGVySWRlbnQgPC0gYXMuY2hhcmFjdGVyKEFsbGNlbGxzLmRhdGFAaWRlbnQpCm5hbWVzKENsdXN0ZXJJZGVudCkgPC0gbmFtZXMoQWxsY2VsbHMuZGF0YUBpZGVudCkKCiMgRmluYWx5IEZhdGVJRCByZXF1aXJlcyB0byBzcGVjaWZ5IHRoZSBpZGVudGl0eSBvZiB0aGUgYXR0cmFjdG9yIHN0YXRlIGNsdXN0ZXJzCkF0dHJhY3RvcnMgPC0gMTo3CmBgYAoKIyMgQ29tcHRlIHRoZSBjZWxscycgZmF0ZSBiaWFzCgpgYGB7ciBjbGFzcy5vdXRwdXQ9InNjcm9sbC0xMDAifQpJbmZlcmVkLkZhdGUuYmlhcyAgPC0gZmF0ZUJpYXMoTm9ybS5NYXQsIENsdXN0ZXJJZGVudCwgQXR0cmFjdG9ycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHogPSAxLWNvcihOb3JtLk1hdCwgbWV0aG9kID0gInNwZWFybWFuIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5ucj0xMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbm5yaD0zMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkYXB0PVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWRlbmNlPTAuOTUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYmZhY3Rvcj01LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlLmRpc3Q9RkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkPTEyMzQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYnRyZWU9TlVMTCkKYGBgCgojIyBJbnNwZWN0IHRoZSB0ZXN0IHNldCB1c2UgYXQgY2xhc3NpZmljYXRpb24gaXRlcmF0aW9uCmBgYHtyfQpBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRGYXRlSUQuaXRlcmF0aW9uIDwtICIwIgpBbGxjZWxscy5kYXRhIDwtIFNldEFsbElkZW50KEFsbGNlbGxzLmRhdGEsIGlkID0gIkZhdGVJRC5pdGVyYXRpb24iKQoKZm9yIChpIGluIHNlcSgwLCBsZW5ndGgoSW5mZXJlZC5GYXRlLmJpYXMkcmZsKSwgYnkgPSA1KVstMV0pIHsKICBpdGVyIDwtIHNlcShpLTQsaSkKICBCYXJjb2RlcyA8LSBjKCkKICBmb3IgKGogaW4gaXRlcikgewogICAgQmFyY29kZXMgPC0gYyhCYXJjb2RlcywgbmFtZXMoSW5mZXJlZC5GYXRlLmJpYXMkcmZsW1tqXV0kdGVzdCRwcmVkaWN0ZWQpKQogIH0KICBBbGxjZWxscy5kYXRhIDwtIFNldElkZW50KEFsbGNlbGxzLmRhdGEsIGNlbGxzLnVzZSA9IEJhcmNvZGVzLCBpZGVudC51c2UgPSBwYXN0ZTAoIml0ZXIgIixpdGVyWzFdLCIgdG8gIiwgaXRlcls0XSkpCn0KYGBgCgoKYGBge3IgZmlnLmRpbT1jKDgsIDYpfQpEaW1QbG90KEFsbGNlbGxzLmRhdGEsCiAgICAgICAgcmVkdWN0aW9uLnVzZSA9ICJzcHJpbmciLAogICAgICAgIGRpbS4xID0gMSxkaW0uMiA9IDIsCiAgICAgICAgZG8ubGFiZWw9VCwKICAgICAgICBsYWJlbC5zaXplID0gMywKICAgICAgICBuby5sZWdlbmQgPSBGLAogICAgICAgIGNvbHMudXNlID0gYygiI2RmZGZkZiIsIGNvbG9ycykpCgpBbGxjZWxscy5kYXRhIDwtIFNldEFsbElkZW50KEFsbGNlbGxzLmRhdGEsIGlkID0gIkNsdXN0ZXIuaWRlbnQiKQpgYGAKCiMjIEltcG9ydCBsaW5lYWdlIGJpYXMgaW50byBTZXVyYXQgbWV0YS5kYXRhCgpgYGB7cn0KcHJvYnMgPC0gSW5mZXJlZC5GYXRlLmJpYXMkcHJvYnNbLHNlcShsZW5ndGgoQXR0cmFjdG9ycykpXQoKQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkcHJvYi5OcjRhMiA8LSBwcm9icyR0MQpBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRwcm9iLkZveHAyYyA8LSBwcm9icyR0MgpBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRwcm9iLlBwcDFyMTRjIDwtIHByb2JzJHQzCkFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJHByb2IuRmV6ZjEgPC0gcHJvYnMkdDQKQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkcHJvYi5Gb3hwMmEgPC0gcHJvYnMkdDUKQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkcHJvYi5Gb3hwMmIgPC0gcHJvYnMkdDYKQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkcHJvYi5OZml4IDwtIHByb2JzJHQ3CmBgYAoKYGBge3IgZmlnLmRpbT1jKDksIDkpLCBmaWcuY2FwPSAiTWFudXNjcmlwdCBGaWcuIDdBIGFuZCBTN0EifQpGZWF0dXJlUGxvdChvYmplY3QgPSBBbGxjZWxscy5kYXRhLAogICAgICAgICAgICBmZWF0dXJlcy5wbG90ID0gYygicHJvYi5OcjRhMiIsICJwcm9iLk5maXgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicHJvYi5QcHAxcjE0YyIsInByb2IuRmV6ZjEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicHJvYi5Gb3hwMmEiLCAicHJvYi5Gb3hwMmIiLCAicHJvYi5Gb3hwMmMiKSwKICAgICAgICAgICAgY29scy51c2UgPSByZXYoUkNvbG9yQnJld2VyOjpicmV3ZXIucGFsKG4gPSAxMSwgbmFtZSA9ICJTcGVjdHJhbCIpKSwKICAgICAgICAgICAgcmVkdWN0aW9uLnVzZSA9ICJzcHJpbmciLAogICAgICAgICAgICBuby5sZWdlbmQgPSBUKQpgYGAKCmBgYHtyIGZpZy5kaW09Yyg4LCA2KSwgZmlnLmNhcD0gIlNwcmluZyBwcm9qZWN0aW9uIHdoZXJlIGNlbGxzIGFyZSBncm91cGVkIGFjY29yZGluZyB0byB0aGUgbGluZWFnZSBmb3Igd2hpY2ggdGhleSByZWNlaXZlZCB0aGUgbWF4aW11bSBuYiBvZiB2b3RlIn0KTmV3LmRhdGEgPC0gZGF0YS5mcmFtZShiYXJjb2RlPUFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJEJhcmNvZGVzLAogICAgICAgICAgICAgICAgICAgICAgIGNsdXN0ZXI9IEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJENsdXN0ZXIuaWRlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgc3ByaW5nMT0gQWxsY2VsbHMuZGF0YUBkciRzcHJpbmdAY2VsbC5lbWJlZGRpbmdzWywxXSwKICAgICAgICAgICAgICAgICAgICAgICBzcHJpbmcyPSBBbGxjZWxscy5kYXRhQGRyJHNwcmluZ0BjZWxsLmVtYmVkZGluZ3NbLDJdLAogICAgICAgICAgICAgICAgICAgICAgIE5yNGEyLmJpYXNlZD0gQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkcHJvYi5OcjRhMiwKICAgICAgICAgICAgICAgICAgICAgICBOZml4LmJpYXNlZD0gQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkcHJvYi5OZml4LAogICAgICAgICAgICAgICAgICAgICAgIFBwcDFyMTRjLmJpYXNlZCA9IEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJHByb2IuUHBwMXIxNGMsCiAgICAgICAgICAgICAgICAgICAgICAgRmV6ZjEuYmlhc2VkID0gQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkcHJvYi5GZXpmMSkKCk5ldy5kYXRhIDwtIE5ldy5kYXRhICU+JSBmaWx0ZXIoIWNsdXN0ZXIgJWluJSBncmVwKCIyNnwyMHwyMSIsIHVuaXF1ZShhcy5jaGFyYWN0ZXIoQWxsY2VsbHMuZGF0YUBpZGVudCkpLCB2YWx1ZSA9IFQpKQoKTmV3LmRhdGEkbGluZWFnZS5iaWFzIDwtIGNvbG5hbWVzKE5ldy5kYXRhWyw1OjhdKVthcHBseShOZXcuZGF0YVssNTo4XSwxLHdoaWNoLm1heCldCgpnZ3Bsb3QoTmV3LmRhdGEsIGFlcyhzcHJpbmcxLCBzcHJpbmcyLCBjb2xvdXIgPSBsaW5lYWdlLmJpYXMpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCIjZTc4MjNhIiwiI2NjMzkxYiIsIiMwMjZjOWEiLCIjZDE0YzhkIikpICsKICBnZW9tX3BvaW50KCkgCmBgYAoKCiMgRXh0cmFjdCB0aGUgTnI0YTIgYW5kIE5maXggImxpbmVhZ2UiIGNlbGxzCgojIyBGaW5kIGNlbGxzIHdpdGggc3Ryb25nIGJpYXNlIHRvd2FyZCBOcjRhMiBuZXVyb25zCgpgYGB7cn0KQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkTnI0YTIuYmlhc2UgPC0gaWZlbHNlKEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJHByb2IuTnI0YTIgPiAwLjUgJiBhYnMoQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkcHJvYi5OZml4LSBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRwcm9iLk5yNGEyKSA+IDAuMjUsICJOcjRhMi5saW5lYWdlIiwgIk90aGVyLmxpbmVhZ2VzIiApCgp0YWJsZShBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSROcjRhMi5iaWFzZSkKYGBgCgoKIyMgRmluZCBjZWxscyB3aXRoIHN0cm9uZyBiaWFzZSB0b3dhcmQgTmZpeCBuZXVyb25zCgpgYGB7cn0KQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkTmZpeC5iaWFzZSA8LSBpZmVsc2UoQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkcHJvYi5OZml4ID4gMC41ICYgYWJzKEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJHByb2IuTmZpeC0gQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkcHJvYi5OcjRhMikgPiAwLjI1LCAiTmZpeC5saW5lYWdlIiwgIk90aGVyLmxpbmVhZ2VzIiApCgp0YWJsZShBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSROZml4LmJpYXNlKQpgYGAKCiMjIFBsb3QgYWxsIGJpYXNlZCBjZWxscyBvbiBzcHJpbmcgZW1iZWRkaW5nCmBgYHtyIGZpZy5kaW09Yyg4LCA2KX0KTnI0YTIgPC0gcm93bmFtZXMoc3Vic2V0KEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhLCBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSROcjRhMi5iaWFzZSA9PSAiTnI0YTIubGluZWFnZSIpKQpOZml4IDwtIHJvd25hbWVzKHN1YnNldChBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSwgQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkTmZpeC5iaWFzZSA9PSAiTmZpeC5saW5lYWdlIikpCgpBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRsaW5lYWdlLmJpYXMgPC0gc2FwcGx5KEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJEJhcmNvZGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHgpIGlmKHggJWluJSBOcjRhMil7eD0iTnI0YTIubGluZWFnZSJ9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZih4ICVpbiUgTmZpeCApe3g9ICJOZml4LmxpbmVhZ2UifQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2V7eD0gIk5vdC5hc3NpZ25lZCJ9KQoKRGltUGxvdChBbGxjZWxscy5kYXRhLAogICAgICAgIGdyb3VwLmJ5ID0gImxpbmVhZ2UuYmlhcyIsCiAgICAgICAgcmVkdWN0aW9uLnVzZSA9ICJzcHJpbmciLAogICAgICAgIGRpbS4xID0gMSwKICAgICAgICBkaW0uMiA9IDIsCiAgICAgICAgZG8ubGFiZWw9VCwKICAgICAgICBsYWJlbC5zaXplID0gNCwKICAgICAgICBjb2xzLnVzZSA9IGMoIiNjYzM5MWIiLCIjOTY5Njk2IiwiIzAyNmM5YSIpLAogICAgICAgIG5vLmxlZ2VuZCA9IEYpCmBgYAoKIyMgSW5zcGVjdCBmYXRlIGJpYXMgYW1vbmcgQVBzCgpgYGB7cn0KIyBGYXRlIGJpYXNlIGluIHByb2dlbml0b3IgZG9tYWluZXMKZGF0YSA8LSBtZWx0KGRhdGEuZnJhbWUoQ2x1c3RlcnMgPSBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRDbHVzdGVyLmlkZW50LAogICAgICAgICAgICAgICAgICAgICAgICBOZml4LnNjb3JlID0gQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkcHJvYi5OZml4LAogICAgICAgICAgICAgICAgICAgICAgICBOcjRhMi5zY29yZSA9IEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJHByb2IuTnI0YTIpKQoKY29sbmFtZXMoZGF0YSkgPC0gYygiQ2x1c3RlcnMiLCAibGluZWFnZSIsICJTY29yZSIpCmBgYAoKYGBge3IgZmlnLmRpbT1jKDYsIDQuNSl9CmRhdGEgJT4lCiAgICAgZmlsdGVyKENsdXN0ZXJzICVpbiUgYygiQVAuVmVudHJhbC5QYWxsaXVtIiwgIkFQLmxhdGVyYWwuUGFsbGl1bS4xIiwgIkFQLmxhdGVyYWwuUGFsbGl1bS4yIiwgIkFQLkRvcnNhbC5QYWxsaXVtIikpICU+JQogICAgIG11dGF0ZShDbHVzdGVycyA9IGZhY3RvcihDbHVzdGVycywgbGV2ZWxzID1jKCJBUC5WZW50cmFsLlBhbGxpdW0iLCAiQVAubGF0ZXJhbC5QYWxsaXVtLjEiLCAiQVAubGF0ZXJhbC5QYWxsaXVtLjIiLCAiQVAuRG9yc2FsLlBhbGxpdW0iKSkpICU+JQogICAgIGdncGxvdChhZXMoeD1mYWN0b3IobGluZWFnZSwgbGV2ZWxzID0gYygiTnI0YTIuc2NvcmUiLCAiTmZpeC5zY29yZSIpICksIHk9U2NvcmUsIGZpbGw9IENsdXN0ZXJzKSkgKyAKICAgICAgICBnZW9tX2JveHBsb3Qobm90Y2g9VFJVRSkgKwogICAgICAgIGdlb21fcG9pbnQocG9zaXRpb249cG9zaXRpb25faml0dGVyZG9kZ2Uoaml0dGVyLndpZHRoID0gMC4yKSwgc2l6ZSA9IC41LCBhZXMoZ3JvdXA9Q2x1c3RlcnMpKSArCiAgICAgICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPSBjKCIjNjhiMDQxIiwgIiNlM2MxNDgiLCAiI2I3ZDE3NCIsICIjZTQ2YjZiIikpICArCiAgICAgICAgeGxhYigiIikKYGBgCgojIyBFeHRyYWN0IE5yNGEyIGFuZCBOZml4IGJpYXNlZCBjZWxscwoKYGBge3IgZmlnLmRpbT1jKDgsIDYpfQojU3Vic2V0IGRhdGFzZXQgdG8ga2VlcCBvbmx5IGNlbGxzIHdoaWNoIHNob3dlZCBzdWZmaWNpZW50IGRpZmZlcmVuY2Ugb2YgZmF0ZSBwcm9iYWJpbGl0eQpWUC5EUC5saW5lYWdlLmNlbGxzIDwtIGMocm93bmFtZXMoc3Vic2V0KEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhLCBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSROcjRhMi5iaWFzZSA9PSAiTnI0YTIubGluZWFnZSIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHJvd25hbWVzKHN1YnNldChBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSwgQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkTmZpeC5iaWFzZSA9PSAiTmZpeC5saW5lYWdlIikpKQoKCiMgV2UgZnVydGhlciBvbmx5IHJldGFpbiBWUCBhbmQgRFAgIHByb2dlbml0b3IgY2x1c3RlcnMKQWxsY2VsbHMuZGF0YSA8LSBTdWJzZXREYXRhKEFsbGNlbGxzLmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxscy51c2UgPSBWUC5EUC5saW5lYWdlLmNlbGxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQucmVtb3ZlID0gYygiQVAubGF0ZXJhbC5QYWxsaXVtLjEiLCAiQVAubGF0ZXJhbC5QYWxsaXVtLjIiKSAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJzZXQucmF3ID0gVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvLmNsZWFuID0gRikKCgpEaW1QbG90KEFsbGNlbGxzLmRhdGEsCiAgICAgICAgcmVkdWN0aW9uLnVzZSA9ICJzcHJpbmciLAogICAgICAgIGRpbS4xID0gMSwKICAgICAgICBkaW0uMiA9IDIsCiAgICAgICAgZG8ubGFiZWw9VCwKICAgICAgICBsYWJlbC5zaXplID0gNCwKICAgICAgICBjb2xzLnVzZSA9IGMoICIjZGZkZmRmIiwiIzY4YjA0MSIsICIjZTQ2YjZiIiwiI2NjM2ExYiIsIiNjYzg3NzgiLCIjZTZiYjliIiAsIiMwNDZjOWEiLCIjNDc4NGEyIiksCiAgICAgICAgbm8ubGVnZW5kID0gVCkKYGBgCgpgYGB7ciBmaWcuZGltPWMoOCwgNiksIGZpZy5jYXA9ICJNYW51c2NyaXB0IEZpZy4gN0IifQpBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRMaW5lYWdlIDwtIGlmZWxzZShBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSROcjRhMi5iaWFzZSA9PSAiTnI0YTIubGluZWFnZSIsICJOcjRhMi5saW5lYWdlIiwgIk5maXgubGluZWFnZSIpCgpEaW1QbG90KEFsbGNlbGxzLmRhdGEsCiAgICAgICAgZ3JvdXAuYnkgPSAiTGluZWFnZSIsCiAgICAgICAgcmVkdWN0aW9uLnVzZSA9ICJzcHJpbmciLAogICAgICAgIGRpbS4xID0gMSwKICAgICAgICBkaW0uMiA9IDIsCiAgICAgICAgZG8ubGFiZWw9VCwKICAgICAgICBjb2xzLnVzZSA9IGMoIiNjYzM5MWIiLCIjMDI2YzlhIiksCiAgICAgICAgbGFiZWwuc2l6ZSA9IDQsCiAgICAgICAgbm8ubGVnZW5kID0gRikKYGBgCgpgYGB7cn0Kcm0obGlzdCA9IGxzKClbIWxzKCkgJWluJSBjKCJBbGxjZWxscy5kYXRhIildKQpgYGAKCiMgQWxpZ25lIGNlbGxzIGFsb25nIFBzZXVkb3RpbWUKCldlIGRlY2lkZWQgdG8gdXNlIHNwcmluZyBzcGFjZSBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24gdG8gZml0IHRoZSBwcmluY2lwYWxlIGN1cnZlIGJlY2F1c2UgaXQgaGFzIGJlZW4gY2FsY3VsYXRlZCBvbiBhbGwgY2VsbHMgdG9nZXRoZXIuIFRodXMgcmVmbGVjdGluZyBwYW4gbmV1cm9uYWwgZGlmZmVyZW50aWF0aW9uIGF4aXMgb2YgdmFyYXRpb24uCgojIyBOcjRhMiBuZXVyb25zIFBzZXVkb3RpbWUgb3JkZXJpbmcKCmBgYHtyfQpOcjRhMi5saW5lYWdlLmNlbGxzIDwtIEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhICU+JQogICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihMaW5lYWdlID09ICJOcjRhMi5saW5lYWdlIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgcHVsbChCYXJjb2RlcykKCiMjIEZpdCBwcmluY2lwYWxlIGN1cnZlIG9uIHRoZSBkYXRhIGluIHRoZSBzcHJpbmcgc3BhY2UKZGF0YS5OcjRhMiA8LSBhcy5kYXRhLmZyYW1lKEFsbGNlbGxzLmRhdGFAZHIkc3ByaW5nQGNlbGwuZW1iZWRkaW5nc1tOcjRhMi5saW5lYWdlLmNlbGxzLDE6Ml0pCgpmaXQgPC0gcHJpbmNpcGFsX2N1cnZlKGFzLm1hdHJpeChkYXRhLk5yNGEyWywxOjJdKSwKICAgICAgICAgICAgICAgICAgICAgICBzbW9vdGhlcj0nc21vb3RoX3NwbGluZScsCiAgICAgICAgICAgICAgICAgICAgICAgdHJhY2U9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICBzdHJldGNoPTIpCgpOcjRhMi5wYy5saW5lIDwtIGFzLmRhdGEuZnJhbWUoZml0JHNbb3JkZXIoZml0JGxhbWJkYSksXSkgI1RoZSBwcmluY2lwYWwgY3VydmUgc21vb3RoZWQKZGF0YS5OcjRhMiRQc2V1ZG90aW1lU2NvcmUgPC0gZml0JGxhbWJkYS9tYXgoZml0JGxhbWJkYSkKCmRhdGEuTnI0YTIkQ2x1c3RlciA8LSBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSAlPiUKICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoTGluZWFnZSA9PSAiTnI0YTIubGluZWFnZSIpICU+JQogICAgICAgICAgICAgICAgICAgICAgIHB1bGwoTmV3Q2x1c3RlcklEKQoKIyBEaXJlY3Rpb24gb2YgdGhlIG1hdHVyYXRpb24gc2NvcmUgdXNpbmcgTmVzIGV4cHJlc3Npb24gKHJldmVydGUgaWYgcG9zaXRpdmUgY29ycmVsYXRpb24pCmlmIChjb3IoZGF0YS5OcjRhMiRQc2V1ZG90aW1lU2NvcmUsIEFsbGNlbGxzLmRhdGFAZGF0YVsnSG1nYTInLCBOcjRhMi5saW5lYWdlLmNlbGxzXSkgPiAwKSB7CiAgZGF0YS5OcjRhMiRQc2V1ZG90aW1lU2NvcmUgPC0gLShkYXRhLk5yNGEyJFBzZXVkb3RpbWVTY29yZSAtIG1heChkYXRhLk5yNGEyJFBzZXVkb3RpbWVTY29yZSkpCn0KYGBgCgojIyBOZml4IG5ldXJvbnMgUHNldWRvdGltZSBvcmRlcmluZwoKYGBge3J9Ck5maXgubGluZWFnZS5jZWxscyA8LSBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSAlPiUKICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihMaW5lYWdlID09ICJOZml4LmxpbmVhZ2UiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgIHB1bGwoQmFyY29kZXMpCgojIyBGaXQgcHJpbmNpcGFsZSBjdXJ2ZSBvbiB0aGUgZGF0YSBpbiB0aGUgc3ByaW5nIHNwYWNlCmRhdGEuTmZpeCA8LSBhcy5kYXRhLmZyYW1lKEFsbGNlbGxzLmRhdGFAZHIkc3ByaW5nQGNlbGwuZW1iZWRkaW5nc1tOZml4LmxpbmVhZ2UuY2VsbHMsMToyXSkKCmZpdCA8LSBwcmluY2lwYWxfY3VydmUoYXMubWF0cml4KGRhdGEuTmZpeFssMToyXSksCiAgICAgICAgICAgICAgICAgICAgICAgc21vb3RoZXI9J3Ntb290aF9zcGxpbmUnLAogICAgICAgICAgICAgICAgICAgICAgIHRyYWNlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgc3RyZXRjaD0yKQoKTmZpeC5wYy5saW5lIDwtIGFzLmRhdGEuZnJhbWUoZml0JHNbb3JkZXIoZml0JGxhbWJkYSksXSkgI1RoZSBwcmluY2lwYWwgY3VydmUgc21vb3RoZWQKZGF0YS5OZml4JFBzZXVkb3RpbWVTY29yZSA8LSBmaXQkbGFtYmRhL21heChmaXQkbGFtYmRhKQoKZGF0YS5OZml4JENsdXN0ZXIgPC0gQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEgJT4lCiAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihMaW5lYWdlID09ICJOZml4LmxpbmVhZ2UiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgcHVsbChOZXdDbHVzdGVySUQpCgoKIyBEaXJlY3Rpb24gb2YgdGhlIG1hdHVyYXRpb24gc2NvcmUgdXNpbmcgTmVzIGV4cHJlc3Npb24gKHJldmVydGUgaWYgcG9zaXRpdmUgY29ycmVsYXRpb24pCmlmIChjb3IoZGF0YS5OZml4JFBzZXVkb3RpbWVTY29yZSwgQWxsY2VsbHMuZGF0YUBkYXRhWydIbWdhMicsIE5maXgubGluZWFnZS5jZWxsc10pID4gMCkgewogIGRhdGEuTmZpeCRQc2V1ZG90aW1lU2NvcmUgPC0gLShkYXRhLk5maXgkUHNldWRvdGltZVNjb3JlIC0gbWF4KGRhdGEuTmZpeCRQc2V1ZG90aW1lU2NvcmUpKQp9CmBgYAoKIyMgQ29tYmluZSBib3RoIHRyYWplY3Rvcnkgb3JkZXJpbmcKCmBgYHtyfQpQc2V1ZG90aW1lIDwtIHJiaW5kKGRhdGEuTnI0YTIgJT4lIGRwbHlyOjpzZWxlY3QoUHNldWRvdGltZVNjb3JlKSwKICAgICAgICAgICAgICAgICAgICBkYXRhLk5maXggJT4lIGRwbHlyOjpzZWxlY3QoUHNldWRvdGltZVNjb3JlKSkKCkFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJFBzZXVkb3RpbWUgPC0gUHNldWRvdGltZVtyb3duYW1lcyhBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSksXQpgYGAKCgpgYGB7ciBmaWcuZGltPWMoOCwgNil9CiNQbG90IFBzZXVkb3RpbWUgc2NvcmUgd2l0aCB0aGUgMiBwcmluY2lwYWwgY3VydmVzCmRhdGEgPC0gYXMuZGF0YS5mcmFtZShBbGxjZWxscy5kYXRhQGRyJHNwcmluZ0BjZWxsLmVtYmVkZGluZ3NbLDE6Ml0pCmRhdGEkUHNldWRvdGltZVNjb3JlIDwtIEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJFBzZXVkb3RpbWUKCmNvbHMgPC0gY29sb3JSYW1wUGFsZXR0ZShicmV3ZXIucGFsKG4gPTExLCBuYW1lID0gIlNwZWN0cmFsIikpKDEwMCkKCmdncGxvdChkYXRhLCBhZXMoc3ByaW5nMSwgc3ByaW5nMikpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj1Qc2V1ZG90aW1lU2NvcmUpLCBzaXplPTIsIHNoYXBlPTE2KSArIAogIHNjYWxlX2NvbG9yX2dyYWRpZW50bihjb2xvdXJzPXJldihjb2xzKSwgbmFtZT0nU3BldWRvdGltZSBzY29yZScpICsKICBnZW9tX2xpbmUoZGF0YT1OZml4LnBjLmxpbmUsIGNvbG9yPSIjY2MzOTFiIiwgc2l6ZT0wLjc3KSArCiAgZ2VvbV9saW5lKGRhdGE9TnI0YTIucGMubGluZSwgY29sb3I9IiMwMjZjOWEiLCBzaXplPTAuNzcpCmBgYAoKYGBge3J9CnJtKGxpc3QgPSBscygpWyFscygpICVpbiUgYygiQWxsY2VsbHMuZGF0YSIpXSkKYGBgCgoKIyBGaW5kIERFRyBiZXR3ZWVuIHRoZSB0d28gdHJhamVjdG9yaWVzIGFuZCBhbG9uZyB0aGUgcHNldWRvdGltZSAKCiMjIEZpbHRlciBnZW5lIGNvdW50cyBtYXRyaXgKYGBge3J9CiNGaWx0ZXIgZ2VuZXMKbnVtLmNlbGxzIDwtIE1hdHJpeDo6cm93U3VtcyhBbGxjZWxscy5kYXRhQHJhdy5kYXRhID4gMCkKZ2VuZXMudXNlIDwtIG5hbWVzKHggPSBudW0uY2VsbHNbbnVtLmNlbGxzID49IDEwXSkKQWxsY2VsbHMuZGF0YUByYXcuZGF0YSA8LSBBbGxjZWxscy5kYXRhQHJhdy5kYXRhW2dlbmVzLnVzZSwgXQoKIyBOb3JtYWxpemF0aW9uIGFuZCB2YXJpYWJsZSBnZW5lIHNlbGVjdGlvbgpBbGxjZWxscy5kYXRhIDwtIE5vcm1hbGl6ZURhdGEob2JqZWN0ID0gQWxsY2VsbHMuZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIkxvZ05vcm1hbGl6ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGUuZmFjdG9yID0gcm91bmQobWVkaWFuKEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJG5VTUkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXkucHJvZ3Jlc3MgPSBGKQoKQWxsY2VsbHMuZGF0YSA8LSBGaW5kVmFyaWFibGVHZW5lcyhvYmplY3QgPSBBbGxjZWxscy5kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4uZnVuY3Rpb24gPSBFeHBNZWFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BlcnNpb24uZnVuY3Rpb24gPSBMb2dWTVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeC5sb3cuY3V0b2ZmID0gMC4wMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4LmhpZ2guY3V0b2ZmID0gNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5LmN1dG9mZiA9IDEuMywgZG8ucGxvdCA9IEYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheS5wcm9ncmVzcyA9IEYpCmxlbmd0aChBbGxjZWxscy5kYXRhQHZhci5nZW5lcykKYGBgCgojIyBJbml0aWFsaXplIGEgbW9ub2NsZSBvYmplY3QKCmBgYHtyfQojIFRyYW5zZmVydCBtZXRhZGF0YQptZXRhLmRhdGEgPC0gZGF0YS5mcmFtZShiYXJjb2RlID0gcm93bmFtZXMoQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEpLAogICAgICAgICAgICAgICAgICAgICAgICBDbHVzdGVyID0gQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkQ2x1c3Rlci5pZGVudCwKICAgICAgICAgICAgICAgICAgICAgICAgTGluZWFnZSA9IEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJExpbmVhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgIFBzZXVkb3RpbWUuU2NvcmUgPSBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRQc2V1ZG90aW1lLAogICAgICAgICAgICAgICAgICAgICAgICByb3cubmFtZXMgPSByb3duYW1lcyhBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSkpCgpBbm5vdC5kYXRhICA8LSBuZXcoJ0Fubm90YXRlZERhdGFGcmFtZScsIGRhdGEgPSBtZXRhLmRhdGEpCgojIFRyYW5zZmVydCBjb3VudCBkYXRhCmNvdW50LmRhdGEgPSBkYXRhLmZyYW1lKGdlbmVfc2hvcnRfbmFtZSA9IHJvd25hbWVzKEFsbGNlbGxzLmRhdGFAcmF3LmRhdGEpLAogICAgICAgICAgICAgICAgICAgICAgICByb3cubmFtZXMgPSByb3duYW1lcyhBbGxjZWxscy5kYXRhQHJhdy5kYXRhKSkKCmZlYXR1cmUuZGF0YSA8LSBuZXcoJ0Fubm90YXRlZERhdGFGcmFtZScsIGRhdGEgPSBjb3VudC5kYXRhKQoKIyBDcmVhdGUgdGhlIENlbGxEYXRhU2V0IG9iamVjdApnYm1fY2RzIDwtIG5ld0NlbGxEYXRhU2V0KGFzLm1hdHJpeChBbGxjZWxscy5kYXRhQHJhdy5kYXRhKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBwaGVub0RhdGEgPSBBbm5vdC5kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVEYXRhID0gZmVhdHVyZS5kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VyRGV0ZWN0aW9uTGltaXQgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb25GYW1pbHkgPSBuZWdiaW5vbWlhbCgpKQpgYGAKCmBgYHtyfQpnYm1fY2RzIDwtIGVzdGltYXRlU2l6ZUZhY3RvcnMoZ2JtX2NkcykKZ2JtX2NkcyA8LSBlc3RpbWF0ZURpc3BlcnNpb25zKGdibV9jZHMpCmdibV9jZHMgPC0gZGV0ZWN0R2VuZXMoZ2JtX2NkcywgbWluX2V4cHIgPSAwLjEpCmBgYAoKYGBge3J9CnJtKGxpc3QgPSBscygpWyFscygpICVpbiUgYygiQWxsY2VsbHMuZGF0YSIsICJnYm1fY2RzIildKQpgYGAKCiMjIFRlc3QgZWFjaCBnZW5lIHRyZW5kIG92ZXIgcHNldWRvdGltZSBzY29yZQoKYGBge3J9CiMgRXhjbHVkZSBjZWxsIGN5Y2xlIGFzc29jaWF0ZWQgZ2VuZXMKQ0NnZW5lcyA8LSBhcy5jaGFyYWN0ZXIocmVhZC50YWJsZSgiLi9Qcm9nZW5pdG9ycy9DZWxsQ3ljbGVHZW5lcy5jc3YiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSBGKVssMV0pCklucHV0LmdlbmVzIDwtIEFsbGNlbGxzLmRhdGFAdmFyLmdlbmVzWyFBbGxjZWxscy5kYXRhQHZhci5nZW5lcyAlaW4lIENDZ2VuZXNdCmBgYAoKYGBge3J9ClNwZXVkb3RpbWUubGluZWFnZXMuZGlmZiA8LSBkaWZmZXJlbnRpYWxHZW5lVGVzdChnYm1fY2RzW0lucHV0LmdlbmVzLF0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVsbE1vZGVsRm9ybXVsYVN0ciA9ICJ+c20ubnMoUHNldWRvdGltZS5TY29yZSwgZGYgPSAzKSpMaW5lYWdlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWR1Y2VkTW9kZWxGb3JtdWxhU3RyID0gIn5zbS5ucyhQc2V1ZG90aW1lLlNjb3JlLCBkZiA9IDMpIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGRldGVjdENvcmVzKCkgLSAyKQoKI0ZpbHRlciBiYXNlZCBvbiBGRFIKU3BldWRvdGltZS5saW5lYWdlcy5kaWZmLmZpbHRlcmVkIDwtIFNwZXVkb3RpbWUubGluZWFnZXMuZGlmZiAlPiUgZmlsdGVyKHF2YWwgPCA1ZS0yKQpgYGAKCiMjIEZpbmQgZGlyZWN0aW9uIG9mIHRoZSBERUcKCldlIGZpbmQgZGlyZWN0aW9uIG9mIHRoZSBERUcgYnkgY2FsY3VsYXRpbmcgdGhlIGFyZWEgYmV0d2VlbiBjdXJ2ZXMgKEFCQykgZm9yIGJyYW5jaC1kZXBlbmRlbnQgZ2VuZXMgYnkgYWRhcHRpbmcgdGhlIG1vbm9jbGUgcGFja2FnZSBmdW5jdGlvbiBgY2FsQUJDc2AuIEdlbmVzIHNwZWNpZmljIEFCQyBpcyBjb21wdXRlZCBvbiBzbW9vdGhlZCBleHByZXNzaW9uIHZhbHVlIG92ZXIgMTAwIHBvaW50cyBhbG9uZyB0aGUgcHNldWRvdGltZQkKCiMjIyBTbW9vdGggZ2VuZSBleHByZXNzaW9uIGFsb25nIHBzZXVkb3RpbWUgCmBgYHtyfQojIENyZWF0ZSBhIG5ldyBwc2V1ZG8tRFYgdmVjdG9yIG9mIDUwMCBwb2ludHMKblBvaW50cyA8LSAxMDAKCm5ld19kYXRhID0gbGlzdCgpCmZvciAoTGluZWFnZSBpbiB1bmlxdWUocERhdGEoZ2JtX2NkcykkTGluZWFnZSkpewogIG5ld19kYXRhW1tsZW5ndGgobmV3X2RhdGEpICsgMV1dID0gZGF0YS5mcmFtZShQc2V1ZG90aW1lLlNjb3JlID0gc2VxKG1pbihwRGF0YShnYm1fY2RzKSRQc2V1ZG90aW1lLlNjb3JlKSwgbWF4KHBEYXRhKGdibV9jZHMpJFBzZXVkb3RpbWUuU2NvcmUpLCBsZW5ndGgub3V0ID0gblBvaW50cyksIExpbmVhZ2U9TGluZWFnZSkKfQoKbmV3X2RhdGEgPSBkby5jYWxsKHJiaW5kLCBuZXdfZGF0YSkKCiMgU21vb3RoIGdlbmUgZXhwcmVzc2lvbgpjdXJ2ZV9tYXRyaXggPC0gZ2VuU21vb3RoQ3VydmVzKGdibV9jZHNbYXMuY2hhcmFjdGVyKFNwZXVkb3RpbWUubGluZWFnZXMuZGlmZi5maWx0ZXJlZCRnZW5lX3Nob3J0X25hbWUpLF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlbmRfZm9ybXVsYSA9ICJ+c20ubnMoUHNldWRvdGltZS5TY29yZSwgZGYgPSAzKSpMaW5lYWdlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxhdGl2ZV9leHByID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdfZGF0YSA9IG5ld19kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzPSBkZXRlY3RDb3JlcygpIC0gMikKYGBgCgojIyMgQ29tcHV0ZSB0aGUgQUJDIGZvciBlYWNoIGdlbmVzCmBgYHtyfQojIEV4dHJhY3QgbWF0cml4IGNvbnRhaW5pbmcgU21vb3RoIGN1cnZlcyBmb3IgZWFjaCBsaW5lYWdlcwpOcjRhMl9jdXJ2ZV9tYXRyaXggPC0gY3VydmVfbWF0cml4WywgMTpuUG9pbnRzXSAjIHRoZSBmaXJzdCAxMDAgcG9pbnRzIGNvcnJlc3BvbmQgdG8gTnI0YTIgY2VsbHMKTmZpeF9jdXJ2ZV9tYXRyaXggPC0gY3VydmVfbWF0cml4WywgKG5Qb2ludHMgKyAxKTooMiAqIG5Qb2ludHMpXQogIApBQkNzX3JlcyA8LSBOcjRhMl9jdXJ2ZV9tYXRyaXggLSBOZml4X2N1cnZlX21hdHJpeCAjIERpcmVjdGlvbiBvZiB0aGUgY29tcGFyaXNvbiA6IHBvc3RpdmUgQUJDcyA8PT4gVXByZWd1bGF0ZWQgaW4gTnI0YTIgbGluZWFnZQpJTFJfcmVzIDwtIGxvZzIoTnI0YTJfY3VydmVfbWF0cml4LyAoTmZpeF9jdXJ2ZV9tYXRyaXggKyAwLjEpKSAjIEF2ZXJhZ2UgbG9nRkMgYmV0d2VlbiB0aGUgMiBjdXJ2ZXMKICAKQUJDc19yZXMgPC0gYXBwbHkoQUJDc19yZXMsIDEsIGZ1bmN0aW9uKHgsIG5Qb2ludHMpIHsKICAgICAgICAgICAgICAgICAgYXZnX2RlbHRhX3ggPC0gKHhbMTooblBvaW50cyAtIDEpXSArIHhbMjooblBvaW50cyldKS8yCiAgICAgICAgICAgICAgICAgIHN0ZXAgPC0gKDEwMC8oblBvaW50cyAtIDEpKQogICAgICAgICAgICAgICAgICByZXMgPC0gcm91bmQoc3VtKGF2Z19kZWx0YV94ICogc3RlcCksIDMpCiAgICAgICAgICAgICAgICAgIHJldHVybihyZXMpfSwKICAgICAgICAgICAgICAgICAgblBvaW50cyA9IG5Qb2ludHMpICMgQ29tcHV0ZSB0aGUgYXJlYSBiZWxvdyB0aGUgY3VydmUKICAKQUJDc19yZXMgPC0gY2JpbmQoQUJDc19yZXMsIElMUl9yZXNbLG5jb2woSUxSX3JlcyldKQpjb2xuYW1lcyhBQkNzX3Jlcyk8LSBjKCJBQkNzIiwgIkVuZHBvaW50X0lMUiIpCgojIEltcG9ydCBBQkMgdmFsdWVzIGludG8gdGhlIERFIHRlc3QgcmVzdWx0cyB0YWJsZQpTcGV1ZG90aW1lLmxpbmVhZ2VzLmRpZmYuZmlsdGVyZWQgPC0gY2JpbmQoU3BldWRvdGltZS5saW5lYWdlcy5kaWZmLmZpbHRlcmVkWywxOjRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQUJDc19yZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTcGV1ZG90aW1lLmxpbmVhZ2VzLmRpZmYuZmlsdGVyZWRbLDU6Nl0pCmBgYAoKIyBDbHVzdGVyIGdlbmVzIGJ5IGV4cHJlc3Npb24gcHJvZmlsZXMgYWxvbmcgdGhlIHR3byB0cmFqZWN0b3JpZXMKCiMjIE5yNGEyIG5ldXJvbnMgc3BlY2lmaWMgdHJhbnNjcmlwdGlvbmFsIHRyYWplY3RvcmllcwoKYGBge3J9CiMgRXh0cmFjdCBOcjRhMiBuZXVyb25zIHRyYWplY3RvcnkgZ2VuZXMKTnI0YTIucmVzIDwtIGFzLmRhdGEuZnJhbWUoU3BldWRvdGltZS5saW5lYWdlcy5kaWZmLmZpbHRlcmVkW1NwZXVkb3RpbWUubGluZWFnZXMuZGlmZi5maWx0ZXJlZCRBQkNzID4gMCxdKQpOcjRhMi5nZW5lcyA8LSByb3cubmFtZXMoTnI0YTIucmVzKQpOcjRhMl9jdXJ2ZV9tYXRyaXggPC0gTnI0YTJfY3VydmVfbWF0cml4W3Jvd25hbWVzKE5yNGEyX2N1cnZlX21hdHJpeCkgJWluJSBOcjRhMi5nZW5lcywgXQpgYGAKCmBgYHtyfQojIEdyb3VwZSBnZW5lcyBpbiA2IGNsdXN0ZXJzIGJ5IHBhcnRpdGlvbmluZyByb3VuZCBtZWRvaWRzCk5yNGEyLmdlbmVzLmNsdXN0ZXJzIDwtIGNsdXN0ZXI6OnBhbShhcy5kaXN0KCgxIC0gY29yKHQoTnI0YTJfY3VydmVfbWF0cml4KSwgbWV0aG9kID0gInBlYXJzb24iKSkpLCBrPTYpCgojIENyZWF0ZSBhIGRhdGFmcmFtZSBzdG9yaW5nIERFRyB0ZXN0IGFuZCBjbHVzdGVyaW5nIHJlc3VsdHMKTnI0YTIuR2VuZS5keW5hbWlxdWUgPC0gZGF0YS5mcmFtZShHZW5lPSBuYW1lcyhOcjRhMi5nZW5lcy5jbHVzdGVycyRjbHVzdGVyaW5nKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwdmFsPU5yNGEyLnJlcyRwdmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF2YWw9TnI0YTIucmVzJHF2YWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQUJDcz1OcjRhMi5yZXMkQUJDcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5lLkNsdXN0ZXJzPSBwYXN0ZTAoIkNsdXN0LiIsIE5yNGEyLmdlbmVzLmNsdXN0ZXJzJGNsdXN0ZXJpbmcpKSAlPiUgYXJyYW5nZShHZW5lLkNsdXN0ZXJzKQoKcm93Lm5hbWVzKE5yNGEyLkdlbmUuZHluYW1pcXVlKSA8LSBOcjRhMi5HZW5lLmR5bmFtaXF1ZSRHZW5lCgp3cml0ZS50YWJsZShOcjRhMi5HZW5lLmR5bmFtaXF1ZSwgIi4vTnI0YTIuR2VuZS5keW5hbWlxdWUuY3N2Iiwgc2VwPSI7IikKYGBgCgpgYGB7ciBmaWcuZGltPWMoOSwgNSksIGZpZy5jYXA9ICJNYW51c2NyaXB0IEZpZy4gN0QifQojIE9yZGVyIHRoZSByb3cgdXNpbmcgc2VyaWF0aW9uCmRzdCA8LSBhcy5kaXN0KCgxLWNvcihzY2FsZSh0KE5yNGEyX2N1cnZlX21hdHJpeCkpLCBtZXRob2QgPSAicGVhcnNvbiIpKSkKcm93LnNlciA8LSBzZXJpYXRlKGRzdCwgbWV0aG9kID0iUjJFIikgIyJSMkUiCmdlbmUub3JkZXIgPC0gcm93bmFtZXMoTnI0YTJfY3VydmVfbWF0cml4W2dldF9vcmRlcihyb3cuc2VyKSxdKQoKYW5uby5jb2xvcnMgPC0gbGlzdChsaW5lYWdlID0gYyhOZml4PSIjY2MzOTFiIiwgTnI0YTI9IiMwMjZjOWEiKSwKICAgICAgICAgICAgICAgICAgICBHZW5lLkNsdXN0ZXJzID0gYyhDbHVzdC4xID0iI2I3OWYwYiIgLCBDbHVzdC4yPSIjZTQ2QjZiIiwgQ2x1c3QuMz0iI2U3ODIzYSIsIENsdXN0LjQ9IiNjYzg3NzgiLCBDbHVzdC41PSIjNjhiMDQxIiwgQ2x1c3QuNj0iIzVhYjc5MyIpKQoKCnBoZWF0bWFwOjpwaGVhdG1hcChjdXJ2ZV9tYXRyaXhbZ2VuZS5vcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKDIwMDoxMDEsICNOZml4IHBvaW50cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMToxMDApXSwgI05yNGEyIHBvaW50cwogICAgICAgICAgICAgICAgICAgc2NhbGUgPSAicm93IiwKICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJfcm93cyA9IEYsCiAgICAgICAgICAgICAgICAgICBjbHVzdGVyX2NvbHMgPSBGLAogICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbl9yb3cgPSBOcjRhMi5HZW5lLmR5bmFtaXF1ZSAlPiUgZHBseXI6OnNlbGVjdChHZW5lLkNsdXN0ZXJzKSwKICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25fY29sID0gZGF0YS5mcmFtZShsaW5lYWdlID0gcmVwKGMoIk5yNGEyIiwgIk5maXgiKSwgZWFjaD0xMDApKSwKICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25fY29sb3JzID0gYW5uby5jb2xvcnMsCiAgICAgICAgICAgICAgICAgICBzaG93X2NvbG5hbWVzID0gRiwKICAgICAgICAgICAgICAgICAgIHNob3dfcm93bmFtZXMgPSBULAogICAgICAgICAgICAgICAgICAgZm9udHNpemVfcm93ID0gMiwKICAgICAgICAgICAgICAgICAgIGNvbG9yID0gcmV2KGJyZXdlci5wYWwoMTEsIlJkQnUiKSksCiAgICAgICAgICAgICAgICAgICBicmVha3MgPSBzZXEoLTIuNSwyLjUsIGxlbmd0aC5vdXQgPSAxMSksCiAgICAgICAgICAgICAgICAgICBtYWluID0gIk5yNGEyIGNlbGxzIGVucmljaGVkIGdlbmVzIGV4cHJlc3Npb24gYWxvbmcgcHNldWRvdGltZSIpCmBgYAoKCiMjIE5maXggbmV1cm9ucyBzcGVjaWZpYyB0cmFuc2NyaXB0aW9uYWwgdHJhamVjdG9yaWVzCgpgYGB7cn0KIyBFeHRyYWN0IE5maXggbmV1cm9ucyB0cmFqZWN0b3J5IGdlbmVzCk5maXgucmVzIDwtIGFzLmRhdGEuZnJhbWUoU3BldWRvdGltZS5saW5lYWdlcy5kaWZmLmZpbHRlcmVkW1NwZXVkb3RpbWUubGluZWFnZXMuZGlmZi5maWx0ZXJlZCRBQkNzIDwgMCxdKQpOZml4LmdlbmVzIDwtIHJvdy5uYW1lcyhOZml4LnJlcykKTmZpeF9jdXJ2ZV9tYXRyaXggPC0gTmZpeF9jdXJ2ZV9tYXRyaXhbcm93bmFtZXMoTmZpeF9jdXJ2ZV9tYXRyaXgpICVpbiUgTmZpeC5nZW5lcywgXQpgYGAKCmBgYHtyfQojIEdyb3VwZSBnZW5lcyBpbiA2IGNsdXN0ZXJzIGJ5IHBhcnRpdGlvbmluZyByb3VuZCBtZWRvaWRzCk5maXguZ2VuZXMuY2x1c3RlcnMgPC0gY2x1c3Rlcjo6cGFtKGFzLmRpc3QoKDEgLSBjb3IodChOZml4X2N1cnZlX21hdHJpeCksIG1ldGhvZCA9ICJwZWFyc29uIikpKSwgaz02KQoKIyBDcmVhdGUgYSBkYXRhZnJhbWUgc3RvcmluZyBERUcgdGVzdCBhbmQgY2x1c3RlcmluZyByZXN1bHRzCk5maXguR2VuZS5keW5hbWlxdWUgPC0gZGF0YS5mcmFtZShHZW5lPSBuYW1lcyhOZml4LmdlbmVzLmNsdXN0ZXJzJGNsdXN0ZXJpbmcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB2YWw9TmZpeC5yZXMkcHZhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdmFsPU5maXgucmVzJHF2YWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQUJDcz1OZml4LnJlcyRBQkNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbmUuQ2x1c3RlcnM9IHBhc3RlMCgiQ2x1c3QuIiwgTmZpeC5nZW5lcy5jbHVzdGVycyRjbHVzdGVyaW5nKSkgJT4lIGFycmFuZ2UoR2VuZS5DbHVzdGVycykKCnJvdy5uYW1lcyhOZml4LkdlbmUuZHluYW1pcXVlKSA8LSBOZml4LkdlbmUuZHluYW1pcXVlJEdlbmUKCndyaXRlLnRhYmxlKE5maXguR2VuZS5keW5hbWlxdWUsICIuL05maXguR2VuZS5keW5hbWlxdWUuY3N2Iiwgc2VwPSI7IikKYGBgCgpgYGB7ciBmaWcuZGltPWMoOSwgNSksIGZpZy5jYXA9ICJNYW51c2NyaXB0IEZpZy4gN0MifQojIE9yZGVyIHRoZSByb3cgdXNpbmcgc2VyaWF0aW9uCmRzdCA8LSBhcy5kaXN0KCgxLWNvcihzY2FsZSh0KE5maXhfY3VydmVfbWF0cml4KSksIG1ldGhvZCA9ICJwZWFyc29uIikpKQpyb3cuc2VyIDwtIHNlcmlhdGUoZHN0LCBtZXRob2QgPSJSMkUiKQpnZW5lLm9yZGVyIDwtIHJvd25hbWVzKE5maXhfY3VydmVfbWF0cml4W2dldF9vcmRlcihyb3cuc2VyKSxdKQoKCnBoZWF0bWFwOjpwaGVhdG1hcChjdXJ2ZV9tYXRyaXhbZ2VuZS5vcmRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKDIwMDoxMDEsICNOZml4IHBvaW50cwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMToxMDApXSwgI05yNGEyIHBvaW50cwogICAgICAgICAgICAgICAgICAgc2NhbGUgPSAicm93IiwKICAgICAgICAgICAgICAgICAgIGNsdXN0ZXJfcm93cyA9IEYsCiAgICAgICAgICAgICAgICAgICBjbHVzdGVyX2NvbHMgPSBGLAogICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbl9yb3cgPSBOZml4LkdlbmUuZHluYW1pcXVlICU+JSBkcGx5cjo6c2VsZWN0KEdlbmUuQ2x1c3RlcnMpLAogICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbl9jb2wgPSBkYXRhLmZyYW1lKGxpbmVhZ2UgPSByZXAoYygiTnI0YTIiLCAiTmZpeCIpLCBlYWNoPTEwMCkpLAogICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbl9jb2xvcnMgPSBhbm5vLmNvbG9ycywKICAgICAgICAgICAgICAgICAgIHNob3dfY29sbmFtZXMgPSBGLAogICAgICAgICAgICAgICAgICAgc2hvd19yb3duYW1lcyA9IFQsCiAgICAgICAgICAgICAgICAgICBmb250c2l6ZV9yb3cgPSAyLAogICAgICAgICAgICAgICAgICAgY29sb3IgPSByZXYoYnJld2VyLnBhbCgxMSwiUmRCdSIpKSwKICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IHNlcSgtMi41LDIuNSwgbGVuZ3RoLm91dCA9IDExKSwKICAgICAgICAgICAgICAgICAgIG1haW4gPSAiTmZpeCBjZWxscyBlbnJpY2hlZCBnZW5lcyBleHByZXNzaW9uIGFsb25nIHBzZXVkb3RpbWUiKQpgYGAKIyBQbG90IHJlbGV2YW50IGdlbmVzIHRyZW5kCgpgYGB7cn0KIyBsb2FkIGN1c3RvbSBwbG90dGluZyBmdW5jdGlvbnMKc291cmNlKCIuL2Z1bmN0aW9ucy9UcmFqZWN0b3JpZXNQbG90RnVuY3Rpb25zLlIiKQpgYGAKCmBgYHtyIGZpZy5kaW09YygxMCw1KSwgZmlnLmNhcD0gIk1hbnVzY3JpcHQgRmlnLiA3RSJ9ClBsb3QuR2VuZXMudHJlbmQoQWxsY2VsbHMuZGF0YSwKICAgICAgICAgICAgICAgICBnZW5lcyA9IGMoIk5maWIiLCAiRGJ4MSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJOZXVyb2Q2IiwgIlBieDMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiUGNwNCIsICJaZmh4MyIpLAogICAgICAgICAgICAgICAgIGNvbG9yLmJ5ID0gImxpbmVhZ2UiLAogICAgICAgICAgICAgICAgIFVzZS5zY2FsZS5kYXRhID0gRikKYGBgCgpgYGB7ciBmaWcuZGltPWMoOSw1KSwgZmlnLmNhcD0gIk1hbnVzY3JpcHQgRmlnLiA3RSJ9ClBsb3QuR2VuZXMudHJlbmQoQWxsY2VsbHMuZGF0YSwKICAgICAgICAgICAgICAgICBnZW5lcyA9IGMoIk5ldXJvZDQiLCAiTmV1cm9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJaZmh4MyIsICJUdWJiMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJIZXkxIiwgIk1hcHQiKSwKICAgICAgICAgICAgICAgICBjb2xvci5ieSA9ICJsaW5lYWdlIiwKICAgICAgICAgICAgICAgICBVc2Uuc2NhbGUuZGF0YSA9IEYpCmBgYAoKYGBge3IgZmlnLmRpbT1jKDksNSksIGZpZy5jYXA9ICJNYW51c2NyaXB0IEZpZy4gUzdCIn0KUGxvdC5HZW5lcy50cmVuZChBbGxjZWxscy5kYXRhLAogICAgICAgICAgICAgICAgIGdlbmVzID0gYygiVGJyMSIsICJFbXgxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5ldXJvZDEiLCAiSGV5MSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJOZXVyb2QyIiwgIkZscnQzIiksCiAgICAgICAgICAgICAgICAgY29sb3IuYnkgPSAibGluZWFnZSIsCiAgICAgICAgICAgICAgICAgVXNlLnNjYWxlLmRhdGEgPSBGKQpgYGAKCmBgYHtyIGZpZy5kaW09Yyg5LDUpLCBmaWcuY2FwPSAiTWFudXNjcmlwdCBGaWcuIFM3QiJ9ClBsb3QuR2VuZXMudHJlbmQoQWxsY2VsbHMuZGF0YSwKICAgICAgICAgICAgICAgICBnZW5lcyA9IGMoIk5maWEiLCAiRG1ydDMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiQ25yMSIsICJTbGMzMGExMCIpLAogICAgICAgICAgICAgICAgIGNvbG9yLmJ5ID0gImxpbmVhZ2UiLAogICAgICAgICAgICAgICAgIFVzZS5zY2FsZS5kYXRhID0gRikKYGBgCgpgYGB7ciBmaWcuZGltPWMoMTAsNSksIGZpZy5jYXA9ICJNYW51c2NyaXB0IEZpZy4gUzdCIn0KUGxvdC5HZW5lcy50cmVuZChBbGxjZWxscy5kYXRhLAogICAgICAgICAgICAgICAgIGdlbmVzID0gYygiTWVpczIiLCAiR20yOTI2MCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJOcjJmMiIsICJEbGV1NyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJaYnRiMjAiLCAiU3ZpbCIpLAogICAgICAgICAgICAgICAgIGNvbG9yLmJ5ID0gImxpbmVhZ2UiLAogICAgICAgICAgICAgICAgIFVzZS5zY2FsZS5kYXRhID0gRikKYGBgCgpgYGB7ciBmaWcuZGltPWMoOSw1KSwgZmlnLmNhcD0gIk1hbnVzY3JpcHQgRmlnLiBTN0IifQpQbG90LkdlbmVzLnRyZW5kKEFsbGNlbGxzLmRhdGEsCiAgICAgICAgICAgICAgICAgZ2VuZXMgPSBjKCJFcGhhMyIsICJQZGxpbTQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiVG94IiwgIlRmYXAyYyIpLAogICAgICAgICAgICAgICAgIGNvbG9yLmJ5ID0gImxpbmVhZ2UiLAogICAgICAgICAgICAgICAgIFVzZS5zY2FsZS5kYXRhID0gRikKYGBgCgpgYGB7ciBmaWcuZGltPWMoOSw1KSwgZmlnLmNhcD0gIk1hbnVzY3JpcHQgRmlnLiBTN0IifQpQbG90LkdlbmVzLnRyZW5kKEFsbGNlbGxzLmRhdGEsCiAgICAgICAgICAgICAgICAgZ2VuZXMgPSBjKCJOZXVyb2cxIiwgIkVvbWVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIkJ0ZzIiLCAiRm94ZzEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiRW14MiIpLAogICAgICAgICAgICAgICAgIGNvbG9yLmJ5ID0gImxpbmVhZ2UiLAogICAgICAgICAgICAgICAgIFVzZS5zY2FsZS5kYXRhID0gRikKYGBgCgojIEluc3BlY3QgZ2VuZXMgd2hpY2ggYmVzdCBwcmVkaWN0IGVhcmx5IGZhdGUgYmlhcyB3aXRoaW4gQlBzCgojIyBFeHRyYWN0IGNlbGxzIGluIEJQIHN0YXRlCgpgYGB7cn0Kc2V0LnNlZWQoMTAwKQojIFJ1biBLbWVhbnMgY2x1c3RlcmluZwpjbCA8LSBrbWVhbnMoY2JpbmQoQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkQVBfc2lnbmF0dXJlMSwKICAgICAgICAgICAgICAgICAgIEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhJEJQX3NpZ25hdHVyZTEsCiAgICAgICAgICAgICAgICAgICBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRFTl9zaWduYXR1cmUxLAogICAgICAgICAgICAgICAgICAgQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEkTE5fc2lnbmF0dXJlMSksIDQpCgpBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSRrbWVhbkNsdXN0IDwtIHBhc3RlMCgiQ2x1c3QuIixjbCRjbHVzdGVyKQpgYGAKCmBgYHtyIGZpZy5kaW09Yyg1LjMsIDQpfQpjb2wucGFsIDwtIHdlc19wYWxldHRlKCJHcmFuZEJ1ZGFwZXN0MSIsIDQsIHR5cGUgPSAiZGlzY3JldGUiKQoKcDEgPC0gZ2dwbG90KEFsbGNlbGxzLmRhdGFAbWV0YS5kYXRhLCBhZXMoeD1BUF9zaWduYXR1cmUxLCB5PUJQX3NpZ25hdHVyZTEsIGNvbG91ciA9IGttZWFuQ2x1c3QpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jb2wucGFsKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKZ2dNYXJnaW5hbChwMSwgdHlwZSA9ICJoaXN0b2dyYW0iLCBmaWxsPSJsaWdodGdyZXkiKQoKRGltUGxvdChBbGxjZWxscy5kYXRhLAogICAgICAgIGdyb3VwLmJ5ID0gImttZWFuQ2x1c3QiLAogICAgICAgIHJlZHVjdGlvbi51c2UgPSAic3ByaW5nIiwKICAgICAgICBjb2xzLnVzZSA9IGNvbC5wYWwsCiAgICAgICAgZGltLjEgPSAxLAogICAgICAgIGRpbS4yID0gMiwKICAgICAgICBkby5sYWJlbD1ULAogICAgICAgIGxhYmVsLnNpemUgPSA0LAogICAgICAgIG5vLmxlZ2VuZCA9IEYpCmBgYAoKCmBgYHtyfQojIEZpbmQgdGhlIGttZWFucyBjbHVzdGVyIHdpdGggdGhlIGhpZ2hlc3QgbWVhbiBQYWxfc2lnbmF0dXJlMSBzY29yZQpNZWFuS2NsdXN0LkJQc2NvcmUgPC0gYWdncmVnYXRlKEJQX3NpZ25hdHVyZTEgfiBrbWVhbkNsdXN0LCBBbGxjZWxscy5kYXRhQG1ldGEuZGF0YSwgbWVhbikKQlBjbHVzdCA8LSBNZWFuS2NsdXN0LkJQc2NvcmUgJT4lIGZpbHRlcihCUF9zaWduYXR1cmUxID09IG1heChCUF9zaWduYXR1cmUxKSkgJT4lIHB1bGwoa21lYW5DbHVzdCkKCiMgRXh0cmFjdCBiYXJjb2RlcyBhbmQgZmlsdGVyIHRoZSBzZXVyYXQgb2JqZWN0CkdsdXQuY2VsbHMgPC0gQWxsY2VsbHMuZGF0YUBtZXRhLmRhdGEgJT4lIGZpbHRlcihrbWVhbkNsdXN0ID09IEJQY2x1c3QpICU+JSBwdWxsKEJhcmNvZGVzKQpCUC5kYXRhIDwtICBTdWJzZXREYXRhKEFsbGNlbGxzLmRhdGEsIGNlbGxzLnVzZSA9IEdsdXQuY2VsbHMgLCBzdWJzZXQucmF3ID0gVCwgIGRvLmNsZWFuID0gRikKYGBgCgpgYGB7ciBmaWcuZGltPWMoNS4zLCA0KX0KRGltUGxvdChCUC5kYXRhLAogICAgICAgIGdyb3VwLmJ5ID0gIkxpbmVhZ2UiLAogICAgICAgIHJlZHVjdGlvbi51c2UgPSAic3ByaW5nIiwKICAgICAgICBkaW0uMSA9IDEsCiAgICAgICAgZGltLjIgPSAyLAogICAgICAgIGRvLmxhYmVsPVQsCiAgICAgICAgY29scy51c2UgPSBjKCIjY2MzOTFiIiwiIzAyNmM5YSIpLAogICAgICAgIGxhYmVsLnNpemUgPSA0LAogICAgICAgIG5vLmxlZ2VuZCA9IEYpCmBgYAoKYGBge3J9CiNGaWx0ZXIgZ2VuZXMKbnVtLmNlbGxzIDwtIE1hdHJpeDo6cm93U3VtcyhCUC5kYXRhQHJhdy5kYXRhID4gMCkKZ2VuZXMudXNlIDwtIG5hbWVzKHggPSBudW0uY2VsbHNbbnVtLmNlbGxzID49IDEwXSkKQlAuZGF0YUByYXcuZGF0YSA8LSBCUC5kYXRhQHJhdy5kYXRhW2dlbmVzLnVzZSwgXQoKIyBOb3JtYWxpemF0aW9uIGFuZCB2YXJpYWJsZSBnZW5lIHNlbGVjdGlvbgpCUC5kYXRhIDwtIE5vcm1hbGl6ZURhdGEob2JqZWN0ID0gQlAuZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIkxvZ05vcm1hbGl6ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGUuZmFjdG9yID0gcm91bmQobWVkaWFuKEJQLmRhdGFAbWV0YS5kYXRhJG5VTUkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BsYXkucHJvZ3Jlc3MgPSBGKQoKQlAuZGF0YSA8LSBGaW5kVmFyaWFibGVHZW5lcyhvYmplY3QgPSBCUC5kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4uZnVuY3Rpb24gPSBFeHBNZWFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BlcnNpb24uZnVuY3Rpb24gPSBMb2dWTVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeC5sb3cuY3V0b2ZmID0gMC4wMywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4LmhpZ2guY3V0b2ZmID0gNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5LmN1dG9mZiA9IDEuMywgZG8ucGxvdCA9IEYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGxheS5wcm9ncmVzcyA9IEYpCmBgYAoKIyMgRmluZCBnZW5lcyB3aGljaCBiZXN0IGNsYXNzaWZ5IEJQIGJldHdlZW4gdGhlIDIgdHJhamVjdG9yaWVzCgpgYGB7cn0KIyBFeGNsdWRlIGNlbGwgY3ljbGUgYXNzb2NpYXRlZCwgbXQgYW5kIHJpYm8gcmlibwpDQ2dlbmVzIDwtIGFzLmNoYXJhY3RlcihyZWFkLnRhYmxlKCIvaG9tZS9tYXR0aGlldS9CdXJlYXUvUi9GaWd1cmVzQ29kZXMvUHJvZ2VuaXRvcnMvQ2VsbEN5Y2xlR2VuZXMuY3N2Iiwgc2VwID0gIlx0IiwgaGVhZGVyID0gRilbLDFdKQpHZW5lc1RvUmVtb3ZlIDwtIGMoZ3JlcChwYXR0ZXJuID0gIiheUnBsfF5ScHN8Xk1ycCkiLCB4ID0gcm93Lm5hbWVzKEJQLmRhdGFAZGF0YSksIHZhbHVlID0gVFJVRSksCiAgICAgICAgICAgICAgICAgICBncmVwKHBhdHRlcm4gPSAiXm10LSIsIHggPSByb3cubmFtZXMoQlAuZGF0YUBkYXRhKSwgdmFsdWUgPSBUUlVFKSwKICAgICAgICAgICAgICAgICAgICJYaXN0IiwgQ0NnZW5lcykKCklucHV0LmdlbmVzIDwtIEJQLmRhdGFAdmFyLmdlbmVzWyFCUC5kYXRhQHZhci5nZW5lcyAlaW4lIEdlbmVzVG9SZW1vdmVdCgojIFNldCBpZGVudApCUC5kYXRhIDwtIFNldEFsbElkZW50KEJQLmRhdGEsIGlkID0gIkxpbmVhZ2UiKQoKCk5maXh2c05yNGEyLkRFZ2VuZXMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gQlAuZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0LnVzZSA9ICJyb2MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50LjEgPSAiTmZpeC5saW5lYWdlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudC4yID0gIk5yNGEyLmxpbmVhZ2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbi5wY3QgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2ZjLnRocmVzaG9sZCA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQuYmFyID0gRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5LnBvcyA9IEYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXMudXNlID0gSW5wdXQuZ2VuZXMpCgpOZml4dnNOcjRhMi5ERWdlbmVzJEdlbmUgPC0gcm93bmFtZXMoTmZpeHZzTnI0YTIuREVnZW5lcykKCndyaXRlLnRhYmxlKE5maXh2c05yNGEyLkRFZ2VuZXMsICIuL0JQX1JPQ19yZXMuY3N2Iiwgc2VwPSI7IikKYGBgCgpgYGB7ciBmaWcuZGltPWMoOSwgNil9CiNTZXQgYSBuZXcgZGF0YSBmcmFtZSB3aGljaCB3aWxsIHN0b3JlIGFsbCB2YXJpYWJsZSBuZWVkZWQgdG8gZ2VuZXJhdGUgdGhlIHZvbGNhbm8gcGxvdApWcGxvdC5kYXRhIDwtIGRhdGEuZnJhbWUoZ2VuZSA9IE5maXh2c05yNGEyLkRFZ2VuZXMkR2VuZSwKICAgICAgICAgICAgICAgICAgICAgICAgIEFVQyA9IE5maXh2c05yNGEyLkRFZ2VuZXMkbXlBVUMsIAogICAgICAgICAgICAgICAgICAgICAgICAgTG9nRkMgPSBOZml4dnNOcjRhMi5ERWdlbmVzJGF2Z19sb2dGQykKCnRlbXBvcmFsLm1vZHVsZSA8LSByb3cubmFtZXMocmVhZC50YWJsZSgiLi9Qcm9nZW5pdG9ycy9UZW1wb3JhbC5nZW5lLmNsdXN0ZXJzLmNzdiIsIHNlcCA9ICI7IiwgaGVhZGVyID0gVCwgcm93Lm5hbWVzID0gMSkpCnNwYXRpYWwubW9kdWxlIDwtIHJvdy5uYW1lcyhyZWFkLnRhYmxlKCIuL1Byb2dlbml0b3JzL1NwYXRpYWwuZ2VuZS5jbHVzdGVycy5jc3YiLCBzZXAgPSAiOyIsIGhlYWRlciA9IFQsIHJvdy5uYW1lcyA9IDEpKQoKVnBsb3QuZGF0YSA8LSBkcGx5cjo6bXV0YXRlKFZwbG90LmRhdGEsIGNvbG9yID0gZHBseXI6OmNhc2Vfd2hlbihWcGxvdC5kYXRhJGdlbmUgJWluJSB0ZW1wb3JhbC5tb2R1bGUgfiAiVGVtcG9yYWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZwbG90LmRhdGEkZ2VuZSAlaW4lIHNwYXRpYWwubW9kdWxlIH4gIlNwYXRpYWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgfiAiTkEiKSkKCmdncGxvdChWcGxvdC5kYXRhLCBhZXMoeCA9IExvZ0ZDLCB5ID0gQVVDLCBjb2xvciA9IGNvbG9yKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDIsIGFscGhhID0gMC44LCBuYS5ybSA9IFQpICsKICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZSA9ICJBUCBtb2R1bGUiLAogICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSBjKCJUZW1wb3JhbCIgPSAiI2NjMzkxYiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNwYXRpYWwiID0gIiMwMjZjOWEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOQSIgPSAiIzk2OTY5NiIpKSArCiAgeGxhYihleHByZXNzaW9uKGxvZygiRm9sZCBjaGFuZ2UiKSkpICsKICB5bGFiKCJBVUMiKSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYygtMC40LCAwLjQpLCBjb2xvdXIgPSAiIzk2OTY5NiIpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBjKDAuNjUsIDAuMzUpLCBjb2xvdXIgPSAiIzk2OTY5NiIpICsKICBnZ3JlcGVsOjpnZW9tX3RleHRfcmVwZWwoYWVzKGxhYmVsPWlmZWxzZShnZW5lICVpbiUgYyh0ZW1wb3JhbC5tb2R1bGUsc3BhdGlhbC5tb2R1bGUpICYgYWJzKFZwbG90LmRhdGEkTG9nRkMpID4gMC40ICYgKFZwbG90LmRhdGEkQVVDID4gMC42NSB8IFZwbG90LmRhdGEkQVVDIDwgMC4zNSksIGFzLmNoYXJhY3RlcihnZW5lKSwnJykpLAogICAgICAgICAgICAgICAgICBib3gucGFkZGluZyAgID0gMC4zNSwgCiAgICAgICAgICAgICAgICAgIHBvaW50LnBhZGRpbmcgPSAwLjUsCiAgICAgICAgICAgICAgICAgIHNlZ21lbnQuY29sb3IgPSAnZ3JleTUwJywKICAgICAgICAgICAgICAgICAgY29sb3VyID0gImJsYWNrIikKCmBgYAoKCiMjIFBsb3QgZ2VuZSBvbiBTcHJpbmcgcGxvdAoKYGBge3IgZmlnLmRpbT1jKDksIDUpfQpGZWF0dXJlUGxvdChvYmplY3QgPSBCUC5kYXRhLAogICAgICAgICAgICBmZWF0dXJlcy5wbG90ID0gYygiRW14MSIsICJaYnRiMjAiKSwKICAgICAgICAgICAgY29scy51c2UgPSBjKCJncmV5OTAiLCBicmV3ZXIucGFsKDksIllsR25CdSIpKSwKICAgICAgICAgICAgcHQuc2l6ZSA9IDIsCiAgICAgICAgICAgIHJlZHVjdGlvbi51c2UgPSAic3ByaW5nIiwKICAgICAgICAgICAgbm8ubGVnZW5kID0gVCwKICAgICAgICAgICAgb3ZlcmxheSA9IEYsCiAgICAgICAgICAgIGRhcmsudGhlbWUgPSBGKQpgYGAKCiMgU2Vzc2lvbiBJbmZvCmBgYHtyfQojZGF0ZQpmb3JtYXQoU3lzLnRpbWUoKSwgIiVkICVCLCAlWSwgJUgsJU0iKQoKI1BhY2thZ2VzIHVzZWQKc2Vzc2lvbkluZm8oKQpgYGA=